Dove sono

Contattami

Address

Abito da qualche parte su questa minuscola sfera nuvolosa. In un pezzo di terra e rocce a forma di stivale, dove l'abitante medio è il furbetto che si lamenta se gli altri fanno i furbetti.

FileMaker One Time Pad

FileMaker One Time Pad
Aug
28
  • Posted by: Mc128k
  • Date: 2016-08-28
  • In:  Programmazione
  • 0 comments

Implementato per una piccola funzione crittografica. Ho incluso tutto il codice necessario. Consiglio una chiave lunga e ben nascosta. Studia bene come funzione un One Time Pad prima di implementarlo, non è un ottimo sistema di sicurezza. Alcune funzioni non sono mie, le ho prese dal sito di Brian Dunning.

 

// Function: OneTimePadEncryptMessage( message ; otp )

====
// 2016 Mc128k
// INSERT STRING VALUES

Let ([
message_length = Length ( message ) ;
otp_length = Length ( otp ) ;
otp_repeated = Repeat ( otp ; Floor ( message_length / otp_length ) ) & Left ( otp ; Mod ( message_length ; otp_length ) ) ;
encrypted_message = ntBitwiseOperation ( "XOR" ; 16 ; Str2Hex ( message ) ; Str2Hex ( otp_repeated ) )
] ; encrypted_message
)
====

// Function: OneTimePadDecryptMessage( ciphertext ; otp )

====
// 2016 Mc128k
// INSERT HEX FOR CIPHER, AND STRING FOR OTP

Let ([
ct_length = Length ( ciphertext ) ;
otp_hex = Str2Hex ( otp ) ;
otp_hex_length = Length ( otp_hex );
otp_repeated = Repeat ( otp_hex ; Floor ( ct_length / otp_hex_length ) ) & Left ( otp_hex ; Mod ( ct_length ; otp_hex_length ) ) ;
message_hex = ntBitwiseOperation ( "XOR" ; 16 ; ciphertext ; otp_repeated )
] ;
Hex2Str ( message_hex )
)
====

// Function: Str2Hex( str )

====
// 2016 Mc128k
// RETURNS UTF-8 CODE POINTS FROM STRING

Let ( [
//h = Upper(Substitute ( hex ; " " ; "" )); // Get rid of spaces and make all hex characters upper case
hl = Length(str);
b = Left (str;1);
//hb = BaseConvert(b;16;10);

// Unicode > Decimal
dec = Code(b) ;

// Decimal > Hex
hex = BaseConvert(dec;10;16);

nh = Right(str;hl-1)
];
If (hl ≥ 1; hex & Str2Hex(nh))
)
====

// Function: Hex2Str( hex )

====
/*
CUSTOM FUNCTION: Hex2Str ( hex )
© 2016 Jake DeGroot, jakedeg@gmail.com

Convert a string of hex-encoded ASCII characters into a human-readable text string.

EXAMPLES:

Hex2Str ( "48 65 6c 6c 6f 20 57 6f 72 6c 64 20 3a 29 " ) // --> "Hello World :)"
*/

Let ( [
h = Upper(Substitute ( hex ; " " ; "" )); // Get rid of spaces and make all hex characters upper case
hl = Length(h);
b = Left (h;2);
hb = BaseConvert(b;16;10);
ch = Char (hb);
nh = Right(h;hl-2)
];
If (hl >1; ch & Hex2Str(nh))
)
====

// Function: BaseConvert( string ; baseFrom ; baseTo )

====
/*
CUSTOM FUNCTION: BaseConvert ( string ; baseFrom ; baseTo )
© 2008 Debi Fuchs of Aptworks Consulting, debi@aptworks.com

Convert a number (up to 10 billion) from one base to another.

EXAMPLES:

BaseConvert( "F1"; 16; 2 ) // --> "11110001"
BaseConvert( -5; 10; 2 ) // --> "-101"
BaseConvert( 255; 10; 16 ) // --> "FF"
BaseConvert( "-101" ; 2; 10 ) // --> "-5"
BaseConvert( -101 ; 2; 10 ) // --> -5
BaseConvert( "FF"; 16; 10 ) // --> "255"
BaseConvert( "-101" ; 16; 2 ) // --> "-100000001"
BaseConvert( "-101" ; 2; 16 ) // --> "-5"
BaseConvert( "FF"; 16; 2 ) // --> "11111111"

IMPLEMENTATION: See comments. No helper functions are required. Limit is set at 10^10 so that the math does not break down, as log calculations on large numbers can be incorrect.

LAST MODIFIED: 14-AUG-2008 by Debi Fuchs of Aptworks Consulting
*/

Case(

// Simulate an "out of range" error if either base is out of range

baseFrom < 2 or baseFrom > 36 or baseTo < 2 or baseTo > 36;
Evaluate("Factorial(-1)");

// Return a null value if the string is null;
string = "";
"";

// Return a 0 value if the string represents 0;
string = 0 or string = "0";
Case( baseTo=10; 0; "0" );

// If the string represents a negative number, subtract from
// 0 the result of calling the function again on the positive version.

GetAsNumber(string) = string and string + 0 < 0; 0 - BaseConvert( Abs( GetAsNumber( string ) ); baseFrom; baseTo ); // If the string otherwise begins with a "minus" symbol, // return the result of appending a negative sign with the result of // calling the function again on the postive version of the string. Left( string; 1 ) = "-"; 0-BaseConvert( Right( string; Length( string ) - 1 ); baseFrom; baseTo ); // Simulate an "out of range" error if string is a number but is either // a base10 number greater than 10 billion, or a non-integer, or // contains characters other than the digits for BaseFrom GetAsNumber(string) = string and ( (baseFrom=10 and GetAsNumber(string)> 10^10) or
GetAsNumber(string)<>Int(string) or
Let(
[
sci_not_pos = Position(string; "e+"; 0; 1);
partial_string = Case( sci_not_pos; Left( string; sci_not_pos - 1 ); string )
];
Filter(
partial_string;
Left(".0123456789"; baseFrom+1)
) <> partial_string
)
);
Evaluate("Factorial(-1)");

// Simulate an "out of range" error if string is a non-number and contains
// characters outside of the digits for BaseFrom

GetAsNumber(string) <> string and
( Filter(
string;
Left("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; baseFrom)
) <> string
);
Evaluate("Factorial(-1)");

// Calculate the integer that the string represents. This is either the
// original string as a number (if we're converting from base 10), or
// the the sum of 1) the product of the first "digit" times a power
// the target base and 2) the result of recursing on the remaining
// "digits" in the string.

Let(

base10Int =
Case(

// If the baseFrom is 10, then the base10 version is (clearly) the
// numeric version of our original string.

baseFrom = 10;
GetAsNumber( string );

// If the string is a number then calculate the first digit,
// multiply it by a power of baseFrom, and add the result of
// recursing on the remainder. (The number might contain scientific
// notation, so we can't use each character of digit as a number).

GetAsNumber(string) = string;
Let(
[
new_string_length = Int( Log( string ) ) + 1;

power_of_10 = 10 ^ ( new_string_length - 1 );
power_of_x = baseFrom ^ ( new_string_length - 1 );

first_digit = Int( string / power_of_10 );

first_digit_char =
Middle(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
first_digit + 1;
1
);

remaining = string - first_digit * power_of_10
];

first_digit_char*power_of_x + BaseConvert (remaining; baseFrom; 10)
);

// If the string is not a number then calculate the number representing
// the first character, multiply it by a power of baseFrom, and add the result
// of recursing on the remainder.

( ( Position(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Left( string; 1 );
0;
1
) - 1 ) * baseFrom ^ ( Length( string ) - 1)
) +
BaseConvert( Right( string; Length( string ) - 1 ); baseFrom; 10 )

);

// Return either the base10Int from above (if base10), use it to calculate
// its representation in the new base, throwing an error on integers that
// are too large to deal with reliably.

Case(

// Simulate an "out of range" error if the base10Int is too large for the math
// to work out
base10Int > 10^10;
Evaluate("Factorial(-1)");

// Return the base10Int from above if the target base is 10.
baseTo = 10;
base10Int;

// Otherwise, calculate the new string as follows: Determine
// the first digit of the new string; Then append it together
// with 1) any subequent zeros, and 2) the result of recursing
// on the remainder using a "fromBase" of 10.

Let(
[
new_string_length = Int( Log( base10Int ) / Log( baseTo ) ) + 1;

power_of_y = baseTo ^ ( new_string_length - 1 );

first_digit = Int( base10Int / power_of_y );

first_digit_char =
Middle(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
first_digit + 1;
1
);

remaining = base10Int - first_digit * power_of_y;

zero_digits_following =
Case(
remaining = 0;
new_string_length - 1;
new_string_length - Int( Log( remaining ) / Log( baseTo ) ) - 2
);

zero_chars =
Left(
"000000000000000000000000000000000000000000000000000" &
"000000000000000000000000000000000000000000000000000" &
"000000000000000000000000000000000000000000000000000";
zero_digits_following
)

];

first_digit_char & zero_chars &
Case( remaining > 0; BaseConvert( remaining; 10; baseTo ) )

)
)
)
)
====

// Function: ntBitwiseOperation( ope ; base ; value1 ; value2 )

====
/*
@ Fast Bitwise Operation

[Format]
ntBitwiseOperation ( ope ; base ; value1 ; value2 )

[Parameters]
ope: "OR", "NOR", "XOR", "AND", "NAND", "NOT","< <",">>"
base: numeral system base of value1 and value2
"2" binary number "8" octal number "16" hexadecimal number
value1: MAX 800bits (bin 800digits, oct 266digits, hex 200digits)
value2: MAX 800bits (bin 800digits, oct 266digits, hex 200digits)
If ope is "NOT", value2 number is ignored.

[Require Functions]
ntRepeat

[Example]
ntBitwiseOperation ( "OR" ; 2 ; "10101" ; "111" ) --> "10111"
ntBitwiseOperation ( "XOR" ; 8 ; "3721" ; "437" ) --> "3316"
ntBitwiseOperation ( "AND" ; 16 ; "EFD8" ; "F0AC7" ) --> "00AC3"
ntBitwiseOperation ( "NOT" ; 16 ; "EFD8" ; "" ) --> "1024"
ntBitwiseOperation ( ">>" ; 2 ; "01101110" ; "3" ) --> "00001101"
ntBitwiseOperation("< <" ; 16 ; "F0" ; "2") --> "C0"

[Performance Comparison]
n bits binary digits bitwise XOR 50,000 records
8bits 16bits 128bits
Function A 103sec 185sec 1381sec
Function B 88sec 168sec 2117sec
this Function 63sec 63sec 76sec

[History]
2014.07.17 Norimichi Tachibana Created
*/

Let ( [
bsize = Case ( base = 2 ; 1 ; base = 8 ; 3 ; 4 ) ;
filter_str = Case ( base = 2 ; "01" ;
base = 8 ; "01234567" ;
"0123456789ABCDEF" ) ;

ope = Upper ( ope ) ;
rep0 = Case ( ope = "NAND" ; 1 ; ope = "NOR" or ope = "NOT" ; 3 ; 0 ) ;
rep1 = If ( ope = "NOR" or ope = "AND" or ope = "NOT" ; 0 ; 1 ) ;
rep2 = Case ( ope = "OR" or ope = "AND" ; 1 ; ope = "NOT" ; 2 ; 0 ) ;
rep3 = If ( ope = "NOR" or ope = "NOT" ; 1 ; 3 ) ;

shift = If ( ope = "< <" or ope = ">>" ; value2 ; 0 ) ;
value1 = Upper ( value1 ) ;
value2 = If ( FilterValues ( "NOT¶< <¶>>" ; ope ) = ope & "¶" ;
0 ; Upper ( value2 ) ) ;
len1 = Length ( value1 ) ;
len2 = Length ( value2 ) ;
len = If ( len1 > len2 ; len1 ; len2 ) ;
blen = len * bsize ;

return = Case (
len1 * bsize > 800 ; "#value1 length error#" & len1;
len2 * bsize > 800 ; "#value2 length error#" ;
Filter ( value1 ; filter_str ) ≠ value1 ; "#value1 illegal digit#" ;
Filter ( value2 ; filter_str ) ≠ value2 ; "#value2 illegal digit#" ;
FilterValues ( "2¶8¶16" ; base ) ≠ base & "¶" ; "#illegal base#" ;
FilterValues ( "OR¶NOR¶XOR¶AND¶NAND¶NOT¶< <¶>>" ; ope ) ≠ ope & "¶" ;
"#illegal operator#" ;
Let ( [
// Pad numbers with zeros to make them the same length
pad = SetPrecision ( 1 / 3 ; 400 ) ;
pad = Substitute ( pad ; [ "3" ; "00" ] ; [ "." ; "" ] ) ;
value1 = Right ( pad & value1 ; len ) ;
value2 = Right ( pad & value2 ; len ) ;

// Convert to binary data
mixvalue = value1 & value2 ;
mixvalue = Case (
base = 2 ; mixvalue ;
base = 8 ; Substitute ( mixvalue ; ["0" ; "000"] ;
["1" ; "001"] ;
["2" ; "010"] ;
["3" ; "011"] ;
["4" ; "100"] ;
["5" ; "101"] ;
["6" ; "110"] ;
["7" ; "111"] ) ;
base = 16 ; Substitute ( mixvalue ; ["0" ; "0000"] ;
["1" ; "0001"] ;
["2" ; "0010"] ;
["3" ; "0011"] ;
["4" ; "0100"] ;
["5" ; "0101"] ;
["6" ; "0110"] ;
["7" ; "0111"] ;
["8" ; "1000"] ;
["9" ; "1001"] ;
["A" ; "1010"] ;
["B" ; "1011"] ;
["C" ; "1100"] ;
["D" ; "1101"] ;
["E" ; "1110"] ;
["F" ; "1111"] ) ) ;
value1 = Left ( mixvalue ; blen ) ;
value2 = Right( mixvalue ; blen ) ;

result = Case (
ope = "< <" ; Right ( value1 & Left ( pad ; shift ) ; blen ) ; ope = ">>" ; Left ( Left ( pad ; shift ) & value1 ; blen ) ;
Let ( [
// Previous calculation on the head 400 bits
p_pos = 1 ;
p_len = If ( blen > 400 ; 400 ; blen ) ;
p_value1 = Left ( value1 ; p_len ) ;
p_value2 = Left ( value2 ; p_len ) ;
p_value = Middle ( ( ( "1." & p_value1 ) +
                                         ( "1." & p_value2 ) ) & pad
                                       ; 3 ; p_len ) ;
result = p_value ;

// Previous calculation on the next 400 bits
p_len = blen - p_len ;
result = result &
If ( p_len > 0 ;
Middle ( ( ( "1." & Middle ( value1 ;
401 ; p_len ) ) +
( "1." & Middle ( value2 ;
401 ; p_len ) ) ) & pad
; 3 ; p_len )
)
] ;
// Perform a bitwise logical operation
Substitute ( result ; [ "0" ; rep0 ] ; [ "1" ; rep1 ] ;
[ "2" ; rep2 ] ; [ "3" ; rep3 ] )
) ) ;

// Convert to original base
result = If ( base = 2 ; result ;
Let ( [
$ntr_pos = 1 ;
$ntr_str = "" ;
$ntr_cmd = "$ntr_str = $ntr_str & Middle ( \"" &
result & "\"; $ntr_pos ; " & bsize &
" ) & \"@\" ;" ;
$ntr_cmd = $ntr_cmd &
"$ntr_pos = $ntr_pos + " & bsize ;
wk_str = ntRepeat ( len ; $ntr_cmd ; "$ntr_str" )
] ;
If ( base = 8 ;
Substitute ( wk_str ; ["000@" ; "0"] ;
["001@" ; "1"] ;
["010@" ; "2"] ;
["011@" ; "3"] ;
["100@" ; "4"] ;
["101@" ; "5"] ;
["110@" ; "6"] ;
["111@" ; "7"] ) ;
Substitute ( wk_str ; ["0000@" ; "0"] ;
["0001@" ; "1"] ;
["0010@" ; "2"] ;
["0011@" ; "3"] ;
["0100@" ; "4"] ;
["0101@" ; "5"] ;
["0110@" ; "6"] ;
["0111@" ; "7"] ;
["1000@" ; "8"] ;
["1001@" ; "9"] ;
["1010@" ; "A"] ;
["1011@" ; "B"] ;
["1100@" ; "C"] ;
["1101@" ; "D"] ;
["1110@" ; "E"] ;
["1111@" ; "F"] ) )
)
)
] ;
result
)
)
] ;
return
)
====

// Function: ntRepeat( times ; statements ; resultValueName )

====
/*
@Non-Recursive Loop Statements

[Format]
ntRepeat( times ; statements ; resultValueName )

[Parameters]
times: Repeat times. 0..1,000,000
statements: One or more statements that are repeated.
resultValueName: Variable Name as return value from this function.

[Example]
===Input===
Let ( [ $c=0; $ret=0 ]; ntRepeat ( 10 ; "$c=$c+1; $ret=$ret+$c" ; "$ret" ) )
===Output===
55 < ----- 1+2+3+4+5+6+7+8+9+10 [History] 2014.07.08 Norimichi Tachibana Created 2014.07.17 Norimichi Tachibana Modified the matters pointed out by "unix, Japan" */ Case ( times > 1000000 ; "?" ; times < 0 ; "?" ; Let ( [ base = Substitute ( SetPrecision ( 1 / 3 ; 333 ) ; [ "3" ; "999" ] ; [ "." ; "9" ] ) ; $stt = "Let([" & Trim ( statements ) & " ] ; 0 ) " ; $wk1 = Substitute ( base ; 9 ; "Evaluate ( $stt ) + " ) & "0" ; $wk2 = Substitute ( Left ( base ; Mod ( times ; 1000 ) ) ; 9 ; "Evaluate ( $stt ) + " ) & "0" ; dummy = Evaluate ( Substitute ( Left ( base ; Div ( times ; 1000 ) ) ; 9 ; "Evaluate ( $wk1 ) + " ) & "Evaluate ( $wk2 )" ) ] ; Evaluate ( resultValueName ) ) ) ==== // Function: Repeat( text ; number ) ==== If (number > 0 ;
text & If ( number > 1 ; Repeat ( text ; number - 1) ; "") ;
""
)
====

Comments (0)
Leave a Comment