mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-26 15:26:43 +00:00
Compare commits
11 commits
998ec863ce
...
d525fd188e
Author | SHA1 | Date | |
---|---|---|---|
|
d525fd188e | ||
|
50a931073b | ||
|
2b847de048 | ||
|
8cf3b95bcb | ||
|
21054dd328 | ||
|
2adf8b9103 | ||
|
44e4368491 | ||
|
ef36afa82b | ||
|
835a239920 | ||
|
3577319d2e | ||
|
d4acf8ee74 |
4 changed files with 1659 additions and 0 deletions
331
src/Home/Crypto/AES128/AES128.ZC
Normal file
331
src/Home/Crypto/AES128/AES128.ZC
Normal file
|
@ -0,0 +1,331 @@
|
|||
#define Nb 4 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
|
||||
#define Nk 4 // The number of 32 bit words in a key.
|
||||
#define Nr 10 // amount of rounds to expand the key
|
||||
|
||||
// could be calculated on the fly too... i guess
|
||||
// https://en.wikipedia.org/wiki/Rijndael_S-box
|
||||
U8 sBox[256] = {
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
// U8 reverse_sBox[256] = {
|
||||
// 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
// 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
// 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
// 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
// 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
// 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
// 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
// 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
// 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
// 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
// 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
// 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
// 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
// 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
// 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
// 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
// };
|
||||
|
||||
U8 Rcon[255] = {
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
|
||||
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
|
||||
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
|
||||
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
|
||||
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
|
||||
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
|
||||
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
|
||||
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
|
||||
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
|
||||
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
|
||||
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
|
||||
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
|
||||
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
|
||||
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
|
||||
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
|
||||
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
|
||||
};
|
||||
|
||||
// Mul2 and Mul3 could be precomputed, but here's a simple implementation
|
||||
// Note: This is a simplified and not optimized version
|
||||
U8 xtime(U8 x) {
|
||||
return (x << 1) ^ (((x >> 7) & 1) * 0x1b);
|
||||
}
|
||||
|
||||
U8 Mul2[256], Mul3[256];
|
||||
|
||||
U0 InitMulTables() {
|
||||
I64 i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
Mul2[i] = xtime(i);
|
||||
Mul3[i] = xtime(i) ^ i;
|
||||
}
|
||||
}
|
||||
|
||||
U0 KeyExpansion(U8 *RoundKey, U8 *Key) {
|
||||
I64 i, j, k;
|
||||
U8 tempa[4]; // Temporary storage array
|
||||
|
||||
// Copy the original key to the first round key
|
||||
for (i = 0; i < Nk; ++i) {
|
||||
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||
}
|
||||
|
||||
// Expand the keys for the remaining rounds
|
||||
for (i = Nk; i < Nb * (Nr + 1); ++i) {
|
||||
// Fetch the previous word
|
||||
k = (i - 1) * 4;
|
||||
tempa[0] = RoundKey[k + 0];
|
||||
tempa[1] = RoundKey[k + 1];
|
||||
tempa[2] = RoundKey[k + 2];
|
||||
tempa[3] = RoundKey[k + 3];
|
||||
|
||||
if (i % Nk == 0) {
|
||||
// Rotate the word and apply S-box substitution
|
||||
U8 u8tmp = tempa[0];
|
||||
tempa[0] = sBox[tempa[1]];
|
||||
tempa[1] = sBox[tempa[2]];
|
||||
tempa[2] = sBox[tempa[3]];
|
||||
tempa[3] = sBox[u8tmp];
|
||||
|
||||
// XOR with Rcon[i/Nk]
|
||||
tempa[0] = tempa[0] ^ Rcon[i / Nk];
|
||||
}
|
||||
|
||||
// XOR tempa with the word Nk positions before
|
||||
j = i * 4; k = (i - Nk) * 4;
|
||||
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
|
||||
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
|
||||
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
|
||||
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
|
||||
}
|
||||
}
|
||||
|
||||
U0 AddRoundKey(U8 round, U8 *state, U8 *RoundKey) {
|
||||
I64 i, j;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
state[j * 4 + i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 SubBytes(U8 *state) {
|
||||
I64 i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
state[i] = sBox[state[i]];
|
||||
}
|
||||
}
|
||||
|
||||
U0 ShiftRows(U8 *state) {
|
||||
U8 temp;
|
||||
|
||||
// Shift the second row (1 shift to the left)
|
||||
temp = state[1];
|
||||
state[1] = state[5];
|
||||
state[5] = state[9];
|
||||
state[9] = state[13];
|
||||
state[13] = temp;
|
||||
|
||||
// Shift the third row (2 shifts to the left)
|
||||
temp = state[2];
|
||||
state[2] = state[10];
|
||||
state[10] = temp;
|
||||
temp = state[6];
|
||||
state[6] = state[14];
|
||||
state[14] = temp;
|
||||
|
||||
// Shift the fourth row (3 shifts to the left)
|
||||
temp = state[3];
|
||||
state[3] = state[15];
|
||||
state[15] = state[11];
|
||||
state[11] = state[7];
|
||||
state[7] = temp;
|
||||
}
|
||||
|
||||
U0 MixColumns(U8 *state) {
|
||||
for (I64 i = 0; i < 4; ++i) {
|
||||
U8 a0 = state[i * 4 + 0];
|
||||
U8 a1 = state[i * 4 + 1];
|
||||
U8 a2 = state[i * 4 + 2];
|
||||
U8 a3 = state[i * 4 + 3];
|
||||
|
||||
U8 r0 = Mul2[a0] ^ Mul3[a1] ^ a2 ^ a3;
|
||||
U8 r1 = a0 ^ Mul2[a1] ^ Mul3[a2] ^ a3;
|
||||
U8 r2 = a0 ^ a1 ^ Mul2[a2] ^ Mul3[a3];
|
||||
U8 r3 = Mul3[a0] ^ a1 ^ a2 ^ Mul2[a3];
|
||||
|
||||
state[i * 4 + 0] = r0;
|
||||
state[i * 4 + 1] = r1;
|
||||
state[i * 4 + 2] = r2;
|
||||
state[i * 4 + 3] = r3;
|
||||
}
|
||||
}
|
||||
|
||||
// U0 InvSubBytes(U8 *state) {
|
||||
// // Implement inverse of SubBytes
|
||||
// }
|
||||
|
||||
// U0 InvShiftRows(U8 *state) {
|
||||
// // Implement inverse of ShiftRows
|
||||
// }
|
||||
|
||||
// U0 InvMixColumns(U8 *state) {
|
||||
// // Implement inverse of MixColumns
|
||||
// }
|
||||
|
||||
// U0 InvCipher(U8 *state, U8 *RoundKey) {
|
||||
// I64 round;
|
||||
// // Start by adding the last round key
|
||||
// AddRoundKey(Nr, state, RoundKey);
|
||||
|
||||
// // Perform the rounds in reverse order
|
||||
// for (round = Nr - 1; round > 0; round--) {
|
||||
// InvShiftRows(state);
|
||||
// InvSubBytes(state);
|
||||
// AddRoundKey(round, state, RoundKey);
|
||||
// InvMixColumns(state);
|
||||
// }
|
||||
|
||||
// // Final round (without MixColumns)
|
||||
// InvShiftRows(state);
|
||||
// InvSubBytes(state);
|
||||
// AddRoundKey(0, state, RoundKey);
|
||||
// }
|
||||
|
||||
U0 Cipher(U8 *state, U8 *RoundKey) {
|
||||
I64 round;
|
||||
// Add the First round key to the state before starting the rounds
|
||||
AddRoundKey(0, state, RoundKey);
|
||||
|
||||
// There will be Nr rounds
|
||||
for (round = 1; round < Nr; ++round) {
|
||||
SubBytes(state);
|
||||
ShiftRows(state);
|
||||
MixColumns(state);
|
||||
AddRoundKey(round, state, RoundKey);
|
||||
}
|
||||
|
||||
// The last round is given below
|
||||
SubBytes(state);
|
||||
ShiftRows(state);
|
||||
AddRoundKey(Nr, state, RoundKey);
|
||||
}
|
||||
|
||||
U0 AES_init_ctx(U8 *ctx, U8 *key) {
|
||||
KeyExpansion(ctx, key);
|
||||
}
|
||||
|
||||
U0 AES_ECB_encrypt(U8 *ctx, U8 *buf) {
|
||||
// Buffer size is assumed to be multiple of 16 bytes! (AES block size)
|
||||
Cipher(buf, ctx);
|
||||
}
|
||||
|
||||
// U0 AES_ECB_decrypt(U8 *ctx, U8 *buf) {
|
||||
// InvCipher(buf, ctx);
|
||||
// }
|
||||
|
||||
U0 PrintHex(U8 *buf, I64 len) {
|
||||
I64 i;
|
||||
for (i = 0; i < len; i++) "%02X ", buf[i];
|
||||
"\n";
|
||||
}
|
||||
|
||||
U8 HexCharToByte(U8 ch) {
|
||||
if (ch >= '0' && ch <= '9') return ch - '0';
|
||||
if (ch >= 'a' && ch <= 'f') return 10 + ch - 'a';
|
||||
if (ch >= 'A' && ch <= 'F') return 10 + ch - 'A';
|
||||
return 0; // Non-hex character
|
||||
}
|
||||
|
||||
U0 HexStringToByteArray(U8 *hexString, U8 *byteArray, I64 byteArrayLength) {
|
||||
I64 i;
|
||||
for (i = 0; i < byteArrayLength; i++) {
|
||||
byteArray[i] = HexCharToByte(hexString[2 * i]) << 4 | HexCharToByte(hexString[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// 9d3492551250741cef1bf7892fabd07b
|
||||
U8 key[16] = {0x9d, 0x34, 0x92, 0x55, 0x12, 0x50, 0x74, 0x1c, 0xef, 0x1b, 0xf7, 0x89, 0x2f, 0xab, 0xd0, 0x7b};
|
||||
// 0c40d19e21ac91fad03b1a8e5349f245
|
||||
U8 buf[16] = {0x0c, 0x40, 0xd1, 0x9e, 0x21, 0xac, 0x91, 0xfa, 0xd0, 0x3b, 0x1a, 0x8e, 0x53, 0x49, 0xf2, 0x45};
|
||||
|
||||
U0 Main() {
|
||||
U8 ctx[176]; // Context (expanded key)
|
||||
|
||||
InitMulTables();
|
||||
AES_init_ctx(ctx, key);
|
||||
AES_ECB_encrypt(ctx, buf);
|
||||
|
||||
// `buf` now contains the ciphertext
|
||||
"Result:\n$$LTRED$$";
|
||||
PrintHex(buf, 16);
|
||||
"\n$$FG$$";
|
||||
}
|
||||
|
||||
Main;
|
||||
|
||||
|
||||
// U0 Main() {
|
||||
|
||||
// U8 ctx[176]; // Context (expanded key)
|
||||
|
||||
// InitMulTables;
|
||||
|
||||
// AES_init_ctx(ctx, key);
|
||||
|
||||
// "ctx:\n";
|
||||
// PrintHex(ctx, 176);
|
||||
// "\n";
|
||||
|
||||
// AES_ECB_encrypt(ctx, buf);
|
||||
// "buf:\n$$LTGREEN$$";
|
||||
// PrintHex(buf, 16);
|
||||
// "\n$$FG$$";
|
||||
// }
|
||||
// Main;
|
||||
|
||||
// // 9d3492551250741cef1bf7892fabd07b
|
||||
// U8 key[16] = {0x9d, 0x34, 0x92, 0x55, 0x12, 0x50, 0x74, 0x1c, 0xef, 0x1b, 0xf7, 0x89, 0x2f, 0xab, 0xd0, 0x7b};
|
||||
// // 0c40d19e21ac91fad03b1a8e5349f245
|
||||
// U8 buf[16] = {0x0c, 0x40, 0xd1, 0x9e, 0x21, 0xac, 0x91, 0xfa, 0xd0, 0x3b, 0x1a, 0x8e, 0x53, 0x49, 0xf2, 0x45};
|
||||
|
||||
// U0 Main(U8 *keyHexString, U8 *plaintextHexString) {
|
||||
|
||||
// U8 ctx[176]; // Context (expanded key)
|
||||
|
||||
// InitMulTables();
|
||||
|
||||
// // Convert hex string to byte array for the key
|
||||
// HexStringToByteArray(keyHexString, key, 16);
|
||||
|
||||
// // Convert hex string to byte array for the plaintext
|
||||
// HexStringToByteArray(plaintextHexString, buf, 16);
|
||||
|
||||
// AES_init_ctx(ctx, key);
|
||||
// AES_ECB_encrypt(ctx, buf);
|
||||
|
||||
// // `buf` now contains the ciphertext
|
||||
// PrintHex(buf, 16);
|
||||
// }
|
||||
|
||||
// // Main("9d3492551250741cef1bf7892fabd07b", "0c40d19e21ac91fad03b1a8e5349f245");
|
181
src/Home/Crypto/ChaCha20/ChaCha20.ZC
Normal file
181
src/Home/Crypto/ChaCha20/ChaCha20.ZC
Normal file
|
@ -0,0 +1,181 @@
|
|||
|
||||
// Rotating bits left
|
||||
U32 RotL32(U32 x, I32 n) {
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
// Packing bytes into a 32-bit unsigned integer
|
||||
U32 Pack4(U8 *a) {
|
||||
U32 res = 0;
|
||||
res |= a[0](U32) << 0 * 8;
|
||||
res |= a[1](U32) << 1 * 8;
|
||||
res |= a[2](U32) << 2 * 8;
|
||||
res |= a[3](U32) << 3 * 8;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Unpacking a 32-bit unsigned integer into bytes
|
||||
U0 UnPack4(U32 src, U8 *dst) {
|
||||
dst[0] = (src >> 0 * 8) & 0xff;
|
||||
dst[1] = (src >> 1 * 8) & 0xff;
|
||||
dst[2] = (src >> 2 * 8) & 0xff;
|
||||
dst[3] = (src >> 3 * 8) & 0xff;
|
||||
}
|
||||
|
||||
// ChaCha20 context structure
|
||||
class chacha20_context {
|
||||
U32 state[16];
|
||||
U32 keystream32[16];
|
||||
U8 key[32];
|
||||
U8 nonce[12];
|
||||
U64 counter;
|
||||
U32 position;
|
||||
};
|
||||
|
||||
U8 *magic_constant = "expand 32-byte k";
|
||||
// Initializing the ChaCha20 block
|
||||
U0 chacha20_init_block(chacha20_context *ctx, U8 *key, U8 *nonce) {
|
||||
MemCopy(ctx->key, key, 32);
|
||||
MemCopy(ctx->nonce, nonce, 12);
|
||||
|
||||
ctx->state[0] = Pack4(magic_constant + 0 * 4);
|
||||
ctx->state[1] = Pack4(magic_constant + 1 * 4);
|
||||
ctx->state[2] = Pack4(magic_constant + 2 * 4);
|
||||
ctx->state[3] = Pack4(magic_constant + 3 * 4);
|
||||
ctx->state[4] = Pack4(key + 0 * 4);
|
||||
ctx->state[5] = Pack4(key + 1 * 4);
|
||||
ctx->state[6] = Pack4(key + 2 * 4);
|
||||
ctx->state[7] = Pack4(key + 3 * 4);
|
||||
ctx->state[8] = Pack4(key + 4 * 4);
|
||||
ctx->state[9] = Pack4(key + 5 * 4);
|
||||
ctx->state[10] = Pack4(key + 6 * 4);
|
||||
ctx->state[11] = Pack4(key + 7 * 4);
|
||||
// 64 bit counter initialized to zero by default.
|
||||
ctx->state[12] = 0;
|
||||
ctx->state[13] = Pack4(nonce + 0 * 4);
|
||||
ctx->state[14] = Pack4(nonce + 1 * 4);
|
||||
ctx->state[15] = Pack4(nonce + 2 * 4);
|
||||
|
||||
MemCopy(ctx->nonce, nonce, 12);
|
||||
}
|
||||
|
||||
// Setting the counter for the ChaCha20 block
|
||||
U0 chacha20_block_set_counter(chacha20_context *ctx, U64 counter) {
|
||||
ctx->state[12] = counter(U32);
|
||||
ctx->state[13] = Pack4(ctx->nonce + 0 * 4) + (counter >> 32)(U32);
|
||||
}
|
||||
|
||||
U0 CHACHA20_QUARTERROUND(U32 *x, I32 a, I32 b, I32 c, I32 d) {
|
||||
x[a] += x[b]; x[d] = RotL32(x[d] ^ x[a], 16);
|
||||
x[c] += x[d]; x[b] = RotL32(x[b] ^ x[c], 12);
|
||||
x[a] += x[b]; x[d] = RotL32(x[d] ^ x[a], 8);
|
||||
x[c] += x[d]; x[b] = RotL32(x[b] ^ x[c], 7);
|
||||
}
|
||||
|
||||
// Generating the next ChaCha20 block
|
||||
U0 chacha20_block_next(chacha20_context *ctx) {
|
||||
I32 i;
|
||||
for (i = 0; i < 16; i++) ctx->keystream32[i] = ctx->state[i];
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 0, 4, 8, 12);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 1, 5, 9, 13);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 2, 6, 10, 14);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 3, 7, 11, 15);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 0, 5, 10, 15);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 1, 6, 11, 12);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 2, 7, 8, 13);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 3, 4, 9, 14);
|
||||
}
|
||||
for (i = 0; i < 16; i++) ctx->keystream32[i] += ctx->state[i];
|
||||
|
||||
U32 *counter = ctx->state + 12;
|
||||
counter[0]++;
|
||||
if (counter[0] == 0) {
|
||||
counter[1]++;
|
||||
if (counter[1] == 0) {
|
||||
// Handle the counter overflow, e.g., print an error message
|
||||
Print("Counter overflow detected\n");
|
||||
// Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializing the ChaCha20 context
|
||||
U0 chacha20_init_context(chacha20_context *ctx, U8 *key, U8 *nonce, U64 counter) {
|
||||
MemSet(ctx, 0, sizeof(chacha20_context));
|
||||
|
||||
chacha20_init_block(ctx, key, nonce);
|
||||
chacha20_block_set_counter(ctx, counter);
|
||||
|
||||
ctx->counter = counter;
|
||||
ctx->position = 64;
|
||||
}
|
||||
|
||||
|
||||
// XOR operation for ChaCha20
|
||||
U0 chacha20_xor(chacha20_context *ctx, U8 *bytes, U64 n_bytes) {
|
||||
U8 *keystream8 = ctx->keystream32(U8*);
|
||||
// was U64 for some reason?
|
||||
I64 i;
|
||||
for (i = 0; i < n_bytes; i++) {
|
||||
if (ctx->position >= 64) {
|
||||
chacha20_block_next(ctx);
|
||||
ctx->position = 0;
|
||||
}
|
||||
bytes[i] ^= keystream8[ctx->position++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Define key and nonce. Ensure they are the correct size (key: 32 bytes, nonce: 12 bytes).
|
||||
U8 key[32] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
};
|
||||
U8 nonce[12] = {
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4A,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
U0 Main() {
|
||||
I64 i;
|
||||
// Define the plaintext message
|
||||
U8 plaintext[16] = "Hello, TempleOS!";
|
||||
U64 plaintext_len = sizeof(plaintext);
|
||||
|
||||
// Allocate space for the ciphertext (same size as plaintext)
|
||||
U8 ciphertext[16];
|
||||
|
||||
// Initialize ChaCha20 context
|
||||
chacha20_context ctx;
|
||||
chacha20_init_context(&ctx, key, nonce, 0); // Counter starts at 0
|
||||
|
||||
// Encrypt the plaintext
|
||||
MemCopy(ciphertext, plaintext, plaintext_len); // Copy plaintext to ciphertext buffer
|
||||
chacha20_xor(&ctx, ciphertext, plaintext_len); // Perform XOR operation
|
||||
|
||||
// Output the encrypted message
|
||||
"Encrypted Message: ";
|
||||
for (i = 0; i < plaintext_len; i++) {
|
||||
"%02X ", ciphertext[i];
|
||||
}
|
||||
"\n";
|
||||
|
||||
// Decrypt the ciphertext (same operation as encryption)
|
||||
chacha20_init_context(&ctx, key, nonce, 0); // Reinitialize context for decryption
|
||||
U8 decrypted[plaintext_len];
|
||||
MemCopy(decrypted, ciphertext, plaintext_len); // Copy ciphertext to decrypted buffer
|
||||
chacha20_xor(&ctx, decrypted, plaintext_len); // Perform XOR operation
|
||||
|
||||
// Output the decrypted message
|
||||
"Decrypted Message: ";
|
||||
for (i = 0; i < plaintext_len; i++) {
|
||||
"%c", decrypted[i];
|
||||
}
|
||||
"\n";
|
||||
}
|
||||
|
||||
Main;
|
272
src/Home/Crypto/TweetNaCl/TweetNaCl.HH
Normal file
272
src/Home/Crypto/TweetNaCl/TweetNaCl.HH
Normal file
|
@ -0,0 +1,272 @@
|
|||
#ifndef TWEETNACL_H
|
||||
#define TWEETNACL_H
|
||||
#define crypto_auth_PRIMITIVE "hmacsha512256"
|
||||
#define crypto_auth crypto_auth_hmacsha512256
|
||||
#define crypto_auth_verify crypto_auth_hmacsha512256_verify
|
||||
#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
|
||||
#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
|
||||
#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
|
||||
#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
|
||||
#define crypto_auth_hmacsha512256_tweet_BYTES 32
|
||||
#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
|
||||
I64 crypto_auth_hmacsha512256_tweet(U8 *, U8 *, I64, U8 *);
|
||||
I64 crypto_auth_hmacsha512256_tweet_verify(U8 *, U8 *, I64, U8 *);
|
||||
#define crypto_auth_hmacsha512256_tweet_VERSION "-"
|
||||
#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
|
||||
#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
|
||||
#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
|
||||
#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
|
||||
#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
|
||||
#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
|
||||
#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
|
||||
#define crypto_box crypto_box_curve25519xsalsa20poly1305
|
||||
#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
|
||||
#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
|
||||
#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
|
||||
#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
|
||||
#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
|
||||
#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
|
||||
#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
|
||||
#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
|
||||
#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet(U8 *, U8 *, I64, U8 *, U8 *, U8 *);
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet_open(U8 *, U8 *, I64, U8 *, U8 *, U8 *);
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet_keypair(U8 *, U8 *);
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(U8 *, U8 *, U8 *);
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet_afternm(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
I64 crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
|
||||
#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
|
||||
#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
|
||||
#define crypto_core_PRIMITIVE "salsa20"
|
||||
#define crypto_core crypto_core_salsa20
|
||||
#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
|
||||
#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
|
||||
#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
|
||||
#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
|
||||
#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
|
||||
#define crypto_core_VERSION crypto_core_salsa20_VERSION
|
||||
#define crypto_core_salsa20_tweet_OUTPUTBYTES 64
|
||||
#define crypto_core_salsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_salsa20_tweet_CONSTBYTES 16
|
||||
I64 crypto_core_salsa20_tweet(U8 *, U8 *, U8 *, U8 *);
|
||||
#define crypto_core_salsa20_tweet_VERSION "-"
|
||||
#define crypto_core_salsa20 crypto_core_salsa20_tweet
|
||||
#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
|
||||
#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
|
||||
#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
|
||||
#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_hsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_CONSTBYTES 16
|
||||
I64 crypto_core_hsalsa20_tweet(U8 *, U8 *, U8 *, U8 *);
|
||||
#define crypto_core_hsalsa20_tweet_VERSION "-"
|
||||
#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
|
||||
#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
|
||||
#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
|
||||
#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
|
||||
#define crypto_hashblocks_PRIMITIVE "sha512"
|
||||
#define crypto_hashblocks crypto_hashblocks_sha512
|
||||
#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
|
||||
#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
|
||||
#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
|
||||
#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
|
||||
#define crypto_hashblocks_sha512_tweet_STATEBYTES 64
|
||||
#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
|
||||
I64 crypto_hashblocks_sha512_tweet(U8 *, U8 *, I64);
|
||||
#define crypto_hashblocks_sha512_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
|
||||
#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
|
||||
#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
|
||||
#define crypto_hashblocks_sha256_tweet_STATEBYTES 32
|
||||
#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
|
||||
I64 crypto_hashblocks_sha256_tweet(U8 *, U8 *, I64);
|
||||
#define crypto_hashblocks_sha256_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
|
||||
#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
|
||||
#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
|
||||
#define crypto_hash_PRIMITIVE "sha512"
|
||||
#define crypto_hash crypto_hash_sha512
|
||||
#define crypto_hash_BYTES crypto_hash_sha512_BYTES
|
||||
#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
|
||||
#define crypto_hash_VERSION crypto_hash_sha512_VERSION
|
||||
#define crypto_hash_sha512_tweet_BYTES 64
|
||||
I64 crypto_hash_sha512_tweet(U8 *, U8 *, I64);
|
||||
#define crypto_hash_sha512_tweet_VERSION "-"
|
||||
#define crypto_hash_sha512 crypto_hash_sha512_tweet
|
||||
#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
|
||||
#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
|
||||
#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
|
||||
#define crypto_hash_sha256_tweet_BYTES 32
|
||||
I64 crypto_hash_sha256_tweet(U8 *, U8 *, I64);
|
||||
#define crypto_hash_sha256_tweet_VERSION "-"
|
||||
#define crypto_hash_sha256 crypto_hash_sha256_tweet
|
||||
#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
|
||||
#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
|
||||
#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
|
||||
#define crypto_onetimeauth_PRIMITIVE "poly1305"
|
||||
#define crypto_onetimeauth crypto_onetimeauth_poly1305
|
||||
#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
|
||||
#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
|
||||
#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
|
||||
#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
|
||||
#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
|
||||
#define crypto_onetimeauth_poly1305_tweet_BYTES 16
|
||||
#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
|
||||
I64 crypto_onetimeauth_poly1305_tweet(U8 *, U8 *, I64, U8 *);
|
||||
I64 crypto_onetimeauth_poly1305_tweet_verify(U8 *, U8 *, I64, U8 *);
|
||||
#define crypto_onetimeauth_poly1305_tweet_VERSION "-"
|
||||
#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
|
||||
#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
|
||||
#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
|
||||
#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
|
||||
#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
|
||||
#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
|
||||
#define crypto_scalarmult_PRIMITIVE "curve25519"
|
||||
#define crypto_scalarmult crypto_scalarmult_curve25519
|
||||
#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
|
||||
#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
|
||||
#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
|
||||
#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
|
||||
#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
|
||||
#define crypto_scalarmult_curve25519_tweet_BYTES 32
|
||||
#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
|
||||
I64 crypto_scalarmult_curve25519_tweet(U8 *, U8 *, U8 *);
|
||||
I64 crypto_scalarmult_curve25519_tweet_base(U8 *, U8 *);
|
||||
#define crypto_scalarmult_curve25519_tweet_VERSION "-"
|
||||
#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
|
||||
#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
|
||||
#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
|
||||
#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
|
||||
#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
|
||||
#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
|
||||
#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
|
||||
#define crypto_secretbox crypto_secretbox_xsalsa20poly1305
|
||||
#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
|
||||
#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
|
||||
#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
I64 crypto_secretbox_xsalsa20poly1305_tweet(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
I64 crypto_secretbox_xsalsa20poly1305_tweet_open(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
|
||||
#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
|
||||
#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
|
||||
#define crypto_sign_PRIMITIVE "ed25519"
|
||||
#define crypto_sign crypto_sign_ed25519
|
||||
#define crypto_sign_open crypto_sign_ed25519_open
|
||||
#define crypto_sign_keypair crypto_sign_ed25519_keypair
|
||||
#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
|
||||
#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
|
||||
#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
|
||||
#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
|
||||
#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
|
||||
#define crypto_sign_ed25519_tweet_BYTES 64
|
||||
#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
|
||||
I64 crypto_sign_ed25519_tweet(U8 *, I64 *, U8 *, I64, U8 *);
|
||||
I64 crypto_sign_ed25519_tweet_open(U8 *, I64 *, U8 *, I64, U8 *);
|
||||
I64 crypto_sign_ed25519_tweet_keypair(U8 *, U8 *);
|
||||
#define crypto_sign_ed25519_tweet_VERSION "-"
|
||||
#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
|
||||
#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
|
||||
#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
|
||||
#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
|
||||
#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
|
||||
#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
|
||||
#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
|
||||
#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
|
||||
#define crypto_stream_PRIMITIVE "xsalsa20"
|
||||
#define crypto_stream crypto_stream_xsalsa20
|
||||
#define crypto_stream_xor crypto_stream_xsalsa20_xor
|
||||
#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
|
||||
#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
|
||||
#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
|
||||
#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
|
||||
#define crypto_stream_xsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
|
||||
I64 crypto_stream_xsalsa20_tweet(U8 *, I64, U8 *, U8 *);
|
||||
I64 crypto_stream_xsalsa20_tweet_xor(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
#define crypto_stream_xsalsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
|
||||
#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
|
||||
#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
|
||||
#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
|
||||
#define crypto_stream_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_salsa20_tweet_NONCEBYTES 8
|
||||
I64 crypto_stream_salsa20_tweet(U8 *, I64, U8 *, U8 *);
|
||||
I64 crypto_stream_salsa20_tweet_xor(U8 *, U8 *, I64, U8 *, U8 *);
|
||||
#define crypto_stream_salsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_salsa20 crypto_stream_salsa20_tweet
|
||||
#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
|
||||
#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
|
||||
#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
|
||||
#define crypto_verify_PRIMITIVE "16"
|
||||
#define crypto_verify crypto_verify_16
|
||||
#define crypto_verify_BYTES crypto_verify_16_BYTES
|
||||
#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
|
||||
#define crypto_verify_VERSION crypto_verify_16_VERSION
|
||||
#define crypto_verify_16_tweet_BYTES 16
|
||||
I64 crypto_verify_16_tweet(U8 *, U8 *);
|
||||
#define crypto_verify_16_tweet_VERSION "-"
|
||||
#define crypto_verify_16 crypto_verify_16_tweet
|
||||
#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
|
||||
#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
|
||||
#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
|
||||
#define crypto_verify_32_tweet_BYTES 32
|
||||
I64 crypto_verify_32_tweet(U8 *, U8 *);
|
||||
#define crypto_verify_32_tweet_VERSION "-"
|
||||
#define crypto_verify_32 crypto_verify_32_tweet
|
||||
#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
|
||||
#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
|
||||
#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
|
||||
#endif
|
875
src/Home/Crypto/TweetNaCl/TweetNaCl.ZC
Normal file
875
src/Home/Crypto/TweetNaCl/TweetNaCl.ZC
Normal file
|
@ -0,0 +1,875 @@
|
|||
// Cd(__DIR__);;
|
||||
// #include "TweetNaCl.HH"
|
||||
// U0 randombytes(U8 *, U64);
|
||||
U0 randombytes(U8 *array, U64 length) {
|
||||
U64 i;
|
||||
for (i = 0; i < length; i++) {
|
||||
array[i] = RandU8();
|
||||
}
|
||||
}
|
||||
|
||||
class gf {
|
||||
I64 data[16];
|
||||
};
|
||||
|
||||
|
||||
U8 _0[16];
|
||||
U8 _9[32] = {9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
|
||||
gf gf0;
|
||||
gf gf1;
|
||||
gf _121665;
|
||||
gf D;
|
||||
gf D2;
|
||||
gf X;
|
||||
gf Y;
|
||||
gf I;
|
||||
|
||||
U0 InitGf() {
|
||||
// Initialize gf1
|
||||
I64 i;
|
||||
gf1.data[0] = 1;
|
||||
for (i = 1; i < 16; i++) gf1.data[i] = 0;
|
||||
|
||||
// Initialize _121665
|
||||
_121665.data[0] = 0xDB41;
|
||||
_121665.data[1] = 1;
|
||||
for (i = 2; i < 16; i++) _121665.data[i] = 0;
|
||||
|
||||
// Initialize D
|
||||
D.data[0] = 0x78a3; D.data[1] = 0x1359; D.data[2] = 0x4dca; D.data[3] = 0x75eb;
|
||||
D.data[4] = 0xd8ab; D.data[5] = 0x4141; D.data[6] = 0x0a4d; D.data[7] = 0x0070;
|
||||
D.data[8] = 0xe898; D.data[9] = 0x7779; D.data[10] = 0x4079; D.data[11] = 0x8cc7;
|
||||
D.data[12] = 0xfe73; D.data[13] = 0x2b6f; D.data[14] = 0x6cee; D.data[15] = 0x5203;
|
||||
|
||||
// Initialize D2
|
||||
D2.data[0] = 0xf159; D2.data[1] = 0x26b2; D2.data[2] = 0x9b94; D2.data[3] = 0xebd6;
|
||||
D2.data[4] = 0xb156; D2.data[5] = 0x8283; D2.data[6] = 0x149a; D2.data[7] = 0x00e0;
|
||||
D2.data[8] = 0xd130; D2.data[9] = 0xeef3; D2.data[10] = 0x80f2; D2.data[11] = 0x198e;
|
||||
D2.data[12] = 0xfce7; D2.data[13] = 0x56df; D2.data[14] = 0xd9dc; D2.data[15] = 0x2406;
|
||||
|
||||
// Initialize X
|
||||
X.data[0] = 0xd51a; X.data[1] = 0x8f25; X.data[2] = 0x2d60; X.data[3] = 0xc956;
|
||||
X.data[4] = 0xa7b2; X.data[5] = 0x9525; X.data[6] = 0xc760; X.data[7] = 0x692c;
|
||||
X.data[8] = 0xdc5c; X.data[9] = 0xfdd6; X.data[10] = 0xe231; X.data[11] = 0xc0a4;
|
||||
X.data[12] = 0x53fe; X.data[13] = 0xcd6e; X.data[14] = 0x36d3; X.data[15] = 0x2169;
|
||||
|
||||
// Initialize Y
|
||||
Y.data[0] = 0x6658; Y.data[1] = 0x6666; Y.data[2] = 0x6666; Y.data[3] = 0x6666;
|
||||
Y.data[4] = 0x6666; Y.data[5] = 0x6666; Y.data[6] = 0x6666; Y.data[7] = 0x6666;
|
||||
Y.data[8] = 0x6666; Y.data[9] = 0x6666; Y.data[10] = 0x6666; Y.data[11] = 0x6666;
|
||||
Y.data[12] = 0x6666; Y.data[13] = 0x6666; Y.data[14] = 0x6666; Y.data[15] = 0x6666;
|
||||
|
||||
// Initialize I
|
||||
I.data[0] = 0xa0b0; I.data[1] = 0x4a0e; I.data[2] = 0x1b27; I.data[3] = 0xc4ee;
|
||||
I.data[4] = 0xe478; I.data[5] = 0xad2f; I.data[6] = 0x1806; I.data[7] = 0x2f43;
|
||||
I.data[8] = 0xd7a7; I.data[9] = 0x3dfb; I.data[10] = 0x0099; I.data[11] = 0x2b4d;
|
||||
I.data[12] = 0xdf0b; I.data[13] = 0x4fc1; I.data[14] = 0x2480; I.data[15] = 0x2b83;
|
||||
}
|
||||
|
||||
InitGf;
|
||||
|
||||
U32 L32(U32 x, I64 c) { return (x << c) | ((x & 0xffffffff) >> (32 - c)); }
|
||||
|
||||
U32 Ld32(U8 *x)
|
||||
{
|
||||
U32 u = x[3];
|
||||
u = (u << 8) | x[2];
|
||||
u = (u << 8) | x[1];
|
||||
return (u << 8) | x[0];
|
||||
}
|
||||
|
||||
U64 Dl64(U8 *x) {
|
||||
U64 i, u = 0;
|
||||
for (i = 0;i < 8;++i) u |= x[i] << 8 * i; // (U64) x[i] << 8 * i;
|
||||
return u;
|
||||
}
|
||||
|
||||
U0 St32(U8 *x, U32 u) {
|
||||
I64 i;
|
||||
for (i = 0;i < 4;++i) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
U0 ts64(U8 *x, U64 u) {
|
||||
I64 i;
|
||||
for (i = 7; i >= 0; --i) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
I64 vn(U8 *x, U8 *y, I64 n) {
|
||||
U32 i, d = 0;
|
||||
for (i = 0;i < n;++i) d |= x[i] ^ y[i];
|
||||
return (1 & ((d - 1) >> 8)) - 1;
|
||||
}
|
||||
|
||||
I64 crypto_verify_16(U8 *x, U8 *y) {
|
||||
return vn(x, y, 16);
|
||||
}
|
||||
|
||||
I64 crypto_verify_32(U8 *x, U8 *y) {
|
||||
return vn(x, y, 32);
|
||||
}
|
||||
|
||||
U0 core(U8 *out, U8 *in, U8 *k, U8 *c, I64 h) {
|
||||
U32 w[16], x[16], y[16], t[4];
|
||||
I64 i, j, m;
|
||||
|
||||
for(i=0;i < 4;++i){
|
||||
x[5 * i] = Ld32(c + 4 * i);
|
||||
x[1 + i] = Ld32(k + 4 * i);
|
||||
x[6 + i] = Ld32(in + 4 * i);
|
||||
x[11 + i] = Ld32(k + 16 + 4 * i);
|
||||
}
|
||||
|
||||
for(i=0;i < 16;++i) y[i] = x[i];
|
||||
for(i=0;i < 20;++i){
|
||||
for(j=0;j < 4;++j){
|
||||
for(m=0;m < 4;++m) t[m] = x[(5 * j + 4 * m) % 16];
|
||||
t[1] ^= L32(t[0] + t[3], 7);
|
||||
t[2] ^= L32(t[1] + t[0], 9);
|
||||
t[3] ^= L32(t[2] + t[1], 13);
|
||||
t[0] ^= L32(t[3] + t[2], 18);
|
||||
for(m=0;m < 4;++m) w[4 * j + (j + m) % 4] = t[m];
|
||||
}
|
||||
for(m=0;m < 16;++m) x[m] = w[m];
|
||||
}
|
||||
|
||||
if (h) {
|
||||
for(i=0;i < 16;++i) x[i] += y[i];
|
||||
for(i=0;i < 4;++i) {
|
||||
x[5 * i] -= Ld32(c + 4 * i);
|
||||
x[6 + i] -= Ld32(in + 4 * i);
|
||||
}
|
||||
for(i=0;i < 4;++i) {
|
||||
St32(out + 4 * i, x[5 * i]);
|
||||
St32(out + 16 + 4 * i, x[6 + i]);
|
||||
}
|
||||
} else {
|
||||
for(i=0;i < 16;++i) St32(out + 4 * i, x[i] + y[i]);
|
||||
}
|
||||
}
|
||||
|
||||
I64 crypto_core_salsa20(U8 *out, U8 *in, U8 *k, U8 *c) {
|
||||
core(out, in, k, c, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_core_hsalsa20(U8 *out, U8 *in, U8 *k, U8 *c) {
|
||||
core(out, in, k, c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
U8 sigma[16] = "expand 32-byte k";
|
||||
|
||||
I64 crypto_stream_salsa20_xor(U8 *c, U8 *m, U64 b, U8 *n, U8 *k) {
|
||||
U8 z[16], x[64];
|
||||
U32 u, i;
|
||||
if (!b) return 0;
|
||||
for (i = 0;i < 16;++i) z[i] = 0;
|
||||
for (i = 0;i < 8;++i) z[i] = n[i];
|
||||
while (b >= 64) {
|
||||
crypto_core_salsa20(x, z, k, sigma);
|
||||
for (i = 0;i < 64;++i){
|
||||
if (m != NULL) {
|
||||
c[i] = m[i] ^ x[i];
|
||||
} else {
|
||||
c[i] = 0 ^ x[i];
|
||||
}
|
||||
}
|
||||
// c[i] = (m ? m[i] : 0) ^ x[i];
|
||||
u = 1;
|
||||
for (i = 8; i < 16; ++i) {
|
||||
u += z[i]; // (u32 z[i])
|
||||
z[i] = u;
|
||||
u >>= 8;
|
||||
}
|
||||
b -= 64;
|
||||
c += 64;
|
||||
if (m) m += 64;
|
||||
}
|
||||
if (b) {
|
||||
crypto_core_salsa20(x, z, k, sigma);
|
||||
for (i = 0;i < b;++i) {
|
||||
// c[i] = (m ? m[i] : 0) ^ x[i];
|
||||
if (m != NULL) {
|
||||
c[i] = m[i] ^ x[i];
|
||||
} else {
|
||||
c[i] = 0 ^ x[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_stream_salsa20(U8 *c, U64 d, U8 *n, U8 *k) {
|
||||
return crypto_stream_salsa20_xor(c, 0, d, n, k);
|
||||
}
|
||||
|
||||
I64 crypto_stream(U8 *c, U64 d, U8 *n, U8 *k) {
|
||||
U8 s[32];
|
||||
crypto_core_hsalsa20(s, n, k, sigma);
|
||||
return crypto_stream_salsa20(c, d, n + 16, s);
|
||||
}
|
||||
|
||||
I64 crypto_stream_xor(U8 *c, U8 *m, U64 d, U8 *n, U8 *k) {
|
||||
U8 s[32];
|
||||
crypto_core_hsalsa20(s, n, k, sigma);
|
||||
return crypto_stream_salsa20_xor(c, m, d, n + 16, s);
|
||||
}
|
||||
|
||||
U0 add1305(U32 *h, U32 *c) {
|
||||
U32 j, u = 0;
|
||||
for (j = 0;j < 17;++j){
|
||||
u += h[j] + c[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
U32 minusp[17] = {
|
||||
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
|
||||
};
|
||||
|
||||
I64 crypto_onetimeauth(U8 *out, U8 *m, U64 n, U8 *k) {
|
||||
U32 s, i, j, u, x[17], r[17], h[17], c[17], g[17];
|
||||
|
||||
for (j = 0;j < 17;++j) r[j] = h[j] = 0;
|
||||
for (j = 0;j < 16;++j) r[j] = k[j];
|
||||
r[3]&=15;
|
||||
r[4]&=252;
|
||||
r[7]&=15;
|
||||
r[8]&=252;
|
||||
r[11]&=15;
|
||||
r[12]&=252;
|
||||
r[15]&=15;
|
||||
|
||||
while (n > 0) {
|
||||
for (j = 0;j < 17;++j) c[j] = 0;
|
||||
for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[j];
|
||||
c[j] = 1;
|
||||
m += j; n -= j;
|
||||
add1305(h, c);
|
||||
for (i = 0;i < 17;++i) {
|
||||
x[i] = 0;
|
||||
for (j = 0;j < 17;++j) {
|
||||
if (j <= i) {
|
||||
x[i] += h[j] * r[i - j];
|
||||
} else {
|
||||
x[i] += h[j] * (320 * r[i + 17 - j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0;i < 17;++i) h[i] = x[i];
|
||||
u = 0;
|
||||
for (j = 0;j < 16;++j) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u & 3;
|
||||
u = 5 * (u >> 2);
|
||||
for (j = 0;j < 16;++j) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u;
|
||||
}
|
||||
for (j = 0;j < 17;++j) g[j] = h[j];
|
||||
add1305(h, minusp);
|
||||
s = -(h[16] >> 7);
|
||||
for (j = 0;j < 17;++j) h[j] ^= s & (g[j] ^ h[j]);
|
||||
for (j = 0;j < 16;++j) c[j] = k[j + 16];
|
||||
c[16] = 0;
|
||||
add1305(h, c);
|
||||
for (j = 0;j < 16;++j) out[j] = h[j];
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_onetimeauth_verify(U8 *h, U8 *m, U64 n, U8 *k) {
|
||||
U8 x[16];
|
||||
crypto_onetimeauth(x, m, n, k);
|
||||
return crypto_verify_16(h, x);
|
||||
}
|
||||
|
||||
I64 crypto_secretbox(U8 *c, U8 *m, U64 d, U8 *n, U8 *k) {
|
||||
I64 i;
|
||||
if (d < 32) return -1;
|
||||
crypto_stream_xor(c, m, d, n, k);
|
||||
crypto_onetimeauth(c + 16, c + 32, d - 32, c);
|
||||
for (i = 0;i < 16;++i) c[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_secretbox_open(U8 *m, U8 *c, U64 d, U8 *n, U8 *k) {
|
||||
I64 i;
|
||||
U8 x[32];
|
||||
if (d < 32) return -1;
|
||||
crypto_stream(x, 32, n, k);
|
||||
if (crypto_onetimeauth_verify(c + 16, c + 32, d - 32, x) != 0) return -1;
|
||||
crypto_stream_xor(m, c, d, n, k);
|
||||
for (i = 0;i < 32;++i) m[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
U0 Set25519(gf r, gf a) {
|
||||
I64 i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
r.data[i] = a.data[i];
|
||||
}
|
||||
}
|
||||
|
||||
U0 Car25519(gf o) {
|
||||
I64 i, c;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o.data[i] += (1 << 16);
|
||||
c = o.data[i] >> 16;
|
||||
o.data[(i + 1) * (i < 15)] += c - 1 + 37 * (c - 1) * (i == 15);
|
||||
o.data[i] -= c << 16;
|
||||
}
|
||||
}
|
||||
|
||||
U0 Sel25519(gf p, gf q, I64 b) {
|
||||
I64 t, i, c = ~(b - 1);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
t = c & (p.data[i] ^ q.data[i]);
|
||||
p.data[i] ^= t;
|
||||
q.data[i] ^= t;
|
||||
}
|
||||
}
|
||||
|
||||
U0 Pack25519(U8 *o, I64 *n) {
|
||||
I64 i, j, b;
|
||||
I64 m[16], t[16];
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
t[i] = n[i];
|
||||
}
|
||||
Car25519(t);
|
||||
Car25519(t);
|
||||
Car25519(t);
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
m[0] = t[0] - 0xffed;
|
||||
for (i = 1; i < 15; i++) {
|
||||
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
|
||||
m[i - 1] &= 0xffff;
|
||||
}
|
||||
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
|
||||
b = (m[15] >> 16) & 1;
|
||||
m[14] &= 0xffff;
|
||||
Sel25519(t, m, 1 - b);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o[2 * i] = t[i] & 0xff;
|
||||
o[2 * i + 1] = t[i] >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
I64 Neq25519(gf a, gf b) {
|
||||
U8 c[32], d[32];
|
||||
Pack25519(c, a);
|
||||
Pack25519(d, b);
|
||||
return crypto_verify_32(c, d);
|
||||
}
|
||||
|
||||
U8 Par25519(gf a) {
|
||||
U8 d[32];
|
||||
Pack25519(d, a);
|
||||
return d[0] & 1;
|
||||
}
|
||||
|
||||
U0 Unpack25519(gf o, U8 *n) {
|
||||
I64 i;
|
||||
for(i=0;i<16;++i) {
|
||||
o.data[i] = n[2 * i] + (n[2 * i + 1] << 8);
|
||||
}
|
||||
o.data[15] &= 0x7fff;
|
||||
}
|
||||
|
||||
// addition
|
||||
U0 A(gf o, gf a, gf b)
|
||||
{
|
||||
I64 i;
|
||||
for (i = 0;i < 16;++i) o.data[i] = a.data[i] + b.data[i];
|
||||
}
|
||||
|
||||
// substraction
|
||||
U0 Z(gf o, gf a, gf b) {
|
||||
I64 i;
|
||||
for (i = 0;i < 16;++i) o.data[i] = a.data[i] - b.data[i];
|
||||
}
|
||||
// multiply
|
||||
U0 M(gf o, gf a, gf b) {
|
||||
I64 i, j, t[31];
|
||||
for (i = 0;i < 31;++i) t[i] = 0;
|
||||
for (i = 0;i < 16;++i) { for (j = 0;j < 16;++j) {t[i + j] += a.data[i] * b.data[j];} }
|
||||
for (i = 0;i < 15;++i) t[i] += 38 * t[i + 16];
|
||||
for (i = 0;i < 16;++i) o.data[i] = t[i];
|
||||
Car25519(o);
|
||||
Car25519(o);
|
||||
}
|
||||
// square
|
||||
U0 S(gf o, gf a) {
|
||||
M(o, a, a);
|
||||
}
|
||||
|
||||
U0 Inv25519(gf *o, gf i) {
|
||||
gf c;
|
||||
I64 a;
|
||||
|
||||
for (a = 0; a < 16; ++a) c.data[a] = i.data[a];
|
||||
for (a = 253; a >= 0; --a) {
|
||||
S(c.data, c.data);
|
||||
if (a != 2 && a != 4) M(c.data, c.data, i.data);
|
||||
}
|
||||
for (a = 0; a < 16; ++a) o->data[a] = c.data[a];
|
||||
}
|
||||
|
||||
U0 Pow2523(gf *o, gf i) {
|
||||
gf c;
|
||||
I64 a;
|
||||
|
||||
for (a = 0; a < 16; ++a) c.data[a] = i.data[a];
|
||||
for (a = 250; a >= 0; --a) {
|
||||
S(c.data, c.data);
|
||||
if (a != 1) M(c.data, c.data, i.data);
|
||||
}
|
||||
for (a = 0; a < 16; ++a) o->data[a] = c.data[a];
|
||||
}
|
||||
|
||||
U0 Add(gf *p, gf *q) {
|
||||
gf a, b, c, d, t, e, f, g, h;
|
||||
|
||||
Z(a, p[1], p[0]);
|
||||
Z(t, q[1], q[0]);
|
||||
M(a, a, t);
|
||||
A(b, p[0], p[1]);
|
||||
A(t, q[0], q[1]);
|
||||
M(b, b, t);
|
||||
M(c, p[3], q[3]);
|
||||
M(c, c, D2);
|
||||
M(d, p[2], q[2]);
|
||||
A(d, d, d);
|
||||
Z(e, b, a);
|
||||
Z(f, d, c);
|
||||
A(g, d, c);
|
||||
A(h, b, a);
|
||||
|
||||
M(p[0], e, f);
|
||||
M(p[1], h, g);
|
||||
M(p[2], g, f);
|
||||
M(p[3], e, h);
|
||||
}
|
||||
|
||||
U0 Cswap(gf *p, gf *q, U8 b) {
|
||||
I64 i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
Sel25519(p[i].data, q[i].data, b);
|
||||
}
|
||||
}
|
||||
|
||||
U0 Pack(U8 *r, gf *p) {
|
||||
gf tx, ty, zi;
|
||||
Inv25519(zi, p[2]);
|
||||
M(tx, p[0], zi);
|
||||
M(ty, p[1], zi);
|
||||
Pack25519(r, ty);
|
||||
r[31] ^= Par25519(tx) << 7;
|
||||
}
|
||||
|
||||
U0 Scalarmult(gf *p, gf q, U8 *s) {
|
||||
I64 i;
|
||||
Set25519(p[0], gf0);
|
||||
Set25519(p[1], gf1);
|
||||
Set25519(p[2], gf1);
|
||||
Set25519(p[3], gf0);
|
||||
for (i = 255; i >= 0; --i) {
|
||||
U8 b = (s[i / 8] >> (i & 7)) & 1;
|
||||
Cswap(p, q, b);
|
||||
Add(q, p);
|
||||
Add(p, p);
|
||||
Cswap(p, q, b);
|
||||
}
|
||||
}
|
||||
|
||||
U0 Scalarbase(gf *p, U8 *s) {
|
||||
gf q[4];
|
||||
Set25519(q[0], X);
|
||||
Set25519(q[1], Y);
|
||||
Set25519(q[2], gf1);
|
||||
M(q[3], X, Y);
|
||||
Scalarmult(p, q, s);
|
||||
}
|
||||
|
||||
I64 crypto_sign_keypair(U8 *pk, U8 *sk)
|
||||
{
|
||||
U8 d[64];
|
||||
gf p[4];
|
||||
I64 i;
|
||||
|
||||
randombytes(sk, 32);
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
Scalarbase(p,d);
|
||||
Pack(pk,p);
|
||||
|
||||
for (i = 0; i < 32; i++) sk[32 + i] = pk[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
I64 crypto_Scalarmult(U8 *q, U8 *n, U8 *p) {
|
||||
U8 z[32];
|
||||
I64 x[80], r, i;
|
||||
gf a, b, c, d, e, f;
|
||||
|
||||
for (i = 0; i < 31; ++i) {
|
||||
z[i] = n[i];
|
||||
}
|
||||
z[31] = (n[31] & 127) | 64;
|
||||
z[0] &= 248;
|
||||
|
||||
Unpack25519(x, p);
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
d.data[i] = a.data[i] = c.data[i] = 0;
|
||||
}
|
||||
a.data[0] = d.data[0] = 1;
|
||||
|
||||
for (i = 254; i >= 0; --i) {
|
||||
r = (z[i >> 3] >> (i & 7)) & 1;
|
||||
Sel25519(a.data,b.data,r);
|
||||
Sel25519(c.data,d.data,r);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
A(c,b,d);
|
||||
Z(b,b,d);
|
||||
S(d,e);
|
||||
S(f,a);
|
||||
M(a,c,a);
|
||||
M(c,b,e);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
S(b,a);
|
||||
Z(c,d,f);
|
||||
M(a,c,_121665);
|
||||
A(a,a,d);
|
||||
M(c,c,a);
|
||||
M(a,d,f);
|
||||
M(d,b,x);
|
||||
S(b,e);
|
||||
Sel25519(a.data,b.data,r);
|
||||
Sel25519(c.data,d.data,r);
|
||||
}
|
||||
|
||||
Inv25519(x+32, c+32);
|
||||
M(x+16, a+16, x+32);
|
||||
Pack25519(q, x+16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_Scalarmult_base(U8 *q, U8 *n) {
|
||||
return crypto_Scalarmult(q, n, _9);
|
||||
}
|
||||
|
||||
I64 crypto_box_keypair(U8 *y, U8 *x) {
|
||||
randombytes(x, 32);
|
||||
return crypto_Scalarmult_base(y, x);
|
||||
}
|
||||
|
||||
I64 crypto_box_beforenm(U8 *k, U8 *y, U8 *x) {
|
||||
U8 s[32];
|
||||
crypto_Scalarmult(s, x, y);
|
||||
return crypto_core_hsalsa20(k, _0, s, sigma);
|
||||
}
|
||||
|
||||
I64 crypto_box_afternm(U8 *c, U8 *m, U64 d, U8 *n, U8 *k) {
|
||||
return crypto_secretbox(c, m, d, n, k);
|
||||
}
|
||||
|
||||
I64 crypto_box_open_afternm(U8 *m, U8 *c, U64 d, U8 *n, U8 *k) {
|
||||
return crypto_secretbox_open(m, c, d, n, k);
|
||||
}
|
||||
|
||||
I64 crypto_box(U8 *c, U8 *m, U64 d, U8 *n, U8 *y, U8 *x) {
|
||||
U8 k[32];
|
||||
crypto_box_beforenm(k, y, x);
|
||||
return crypto_box_afternm(c, m, d, n, k);
|
||||
}
|
||||
|
||||
I64 crypto_box_open(U8 *m, U8 *c, U64 d, U8 *n, U8 *y, U8 *x) {
|
||||
U8 k[32];
|
||||
crypto_box_beforenm(k, y, x);
|
||||
return crypto_box_open_afternm(m, c, d, n, k);
|
||||
}
|
||||
|
||||
U64 R(U64 x, I64 c) { return (x >> c) | (x << (64 - c)); }
|
||||
U64 Ch(U64 x, U64 y, U64 z) { return (x & y) ^ (~x & z); }
|
||||
U64 Maj(U64 x, U64 y, U64 z) { return (x & y) ^ (x & z) ^ (y & z); }
|
||||
U64 Sigma0(U64 x) { return R(x, 28) ^ R(x, 34) ^ R(x, 39); }
|
||||
U64 Sigma1(U64 x) { return R(x, 14) ^ R(x, 18) ^ R(x, 41); }
|
||||
U64 sigma0(U64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
|
||||
U64 sigma1(U64 x) { return R(x, 19) ^ R(x, 61) ^ (x >> 6); }
|
||||
|
||||
U64 K[80] =
|
||||
{
|
||||
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
|
||||
0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
|
||||
0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
|
||||
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
|
||||
0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
|
||||
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
|
||||
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
|
||||
0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
|
||||
0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
|
||||
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
|
||||
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
|
||||
0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
|
||||
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
|
||||
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
|
||||
0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
|
||||
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
|
||||
0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
|
||||
0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
|
||||
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
|
||||
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
|
||||
};
|
||||
|
||||
I64 crypto_hashblocks(U8 *x, U8 *m, U64 n) {
|
||||
U64 z[8], b[8], a[8], w[16], t;
|
||||
I64 i, j;
|
||||
|
||||
for (i = 0;i < 8;++i) z[i] = a[i] = Dl64(x + 8 * i);
|
||||
|
||||
while (n >= 128) {
|
||||
for (i = 0;i < 16;++i) w[i] = Dl64(m + 8 * i);
|
||||
|
||||
for (i = 0;i < 80;++i) {
|
||||
for (j = 0;j < 8;++j) b[j] = a[j];
|
||||
t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
|
||||
b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
|
||||
b[3] += t;
|
||||
for (j = 0;j < 8;++j) a[(j+1)%8] = b[j];
|
||||
if (i%16 == 15)
|
||||
for (j = 0;j < 16;++j) w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
|
||||
}
|
||||
|
||||
for (i = 0;i < 8;++i) { a[i] += z[i]; z[i] = a[i]; }
|
||||
|
||||
m += 128;
|
||||
n -= 128;
|
||||
}
|
||||
|
||||
for (i = 0;i < 8;++i) ts64(x + 8 * i, z[i]);
|
||||
|
||||
return n;
|
||||
}
|
||||
U8 iv[64] = {
|
||||
0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
|
||||
0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
|
||||
0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
|
||||
0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
|
||||
0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
|
||||
0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
|
||||
0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
|
||||
0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
|
||||
};
|
||||
|
||||
I64 crypto_hash(U8 *out, U8 *m, U64 n) {
|
||||
U8 h[64], x[256];
|
||||
U64 i, b = n;
|
||||
|
||||
for (i = 0;i < 64;++i) h[i] = iv[i];
|
||||
|
||||
crypto_hashblocks(h, m, n);
|
||||
m += n;
|
||||
n &= 127;
|
||||
m -= n;
|
||||
|
||||
for (i = 0;i < 256;++i) x[i] = 0;
|
||||
for (i = 0;i < n;++i) x[i] = m[i];
|
||||
x[n] = 128;
|
||||
|
||||
n = 256 - 128 * (n < 112);
|
||||
x[n - 9] = b >> 61;
|
||||
ts64(x + n - 8, b << 3);
|
||||
crypto_hashblocks(h, x, n);
|
||||
for (i = 0;i < 64;++i) out[i] = h[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U0 Add(gf *p, gf *q) {
|
||||
gf a, b, c, d, t, e, f, g, h;
|
||||
|
||||
Z(a, p[1], p[0]);
|
||||
Z(t, q[1], q[0]);
|
||||
M(a, a, t);
|
||||
A(b, p[0], p[1]);
|
||||
A(t, q[0], q[1]);
|
||||
M(b, b, t);
|
||||
M(c, p[3], q[3]);
|
||||
M(c, c, D2);
|
||||
M(d, p[2], q[2]);
|
||||
A(d, d, d);
|
||||
Z(e, b, a);
|
||||
Z(f, d, c);
|
||||
A(g, d, c);
|
||||
A(h, b, a);
|
||||
|
||||
M(p[0], e, f);
|
||||
M(p[1], h, g);
|
||||
M(p[2], g, f);
|
||||
M(p[3], e, h);
|
||||
}
|
||||
|
||||
U64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
|
||||
|
||||
U0 modL(U8 *r, I64 *x) {
|
||||
I64 carry, i, j, index;
|
||||
for (i = 63; i >= 32; --i) {
|
||||
carry = 0;
|
||||
for (j = i - 32; j < i - 12; ++j) {
|
||||
index = j - (i - 32);
|
||||
if (index >= 0 && index < 32) {
|
||||
x[j] += carry - 16 * x[i] * L[index];
|
||||
}
|
||||
carry = (x[j] + 128) >> 8;
|
||||
x[j] -= carry << 8;
|
||||
}
|
||||
x[j] += carry;
|
||||
x[i] = 0;
|
||||
}
|
||||
carry = 0;
|
||||
for (j = 0; j < 32; j++) {
|
||||
x[j] += carry - (x[31] >> 4) * L[j];
|
||||
carry = x[j] >> 8;
|
||||
x[j] &= 255;
|
||||
}
|
||||
for (j = 0; j < 32; j++) x[j] -= carry * L[j];
|
||||
for (i = 0; i < 32; i++) {
|
||||
x[i+1] += x[i] >> 8;
|
||||
r[i] = x[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
U0 reduce(U8 *r)
|
||||
{
|
||||
I64 x[64], i;
|
||||
for (i = 0; i < 64; i++) x[i] = r[i]; //(U64) r[i];
|
||||
for (i = 0; i < 64; i++) r[i] = 0;
|
||||
modL(r, x);
|
||||
}
|
||||
|
||||
I64 crypto_sign(U8 *sm, U64 *smlen, U8 *m, U64 n, U8 *sk)
|
||||
{
|
||||
U8 d[64], h[64], r[64];
|
||||
I64 i, j, x[64];
|
||||
gf p[4];
|
||||
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
*smlen = n+64;
|
||||
for (i = 0; i < n; i++) sm[64 + i] = m[i];
|
||||
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
|
||||
|
||||
crypto_hash(r, sm+32, n+32);
|
||||
reduce(r);
|
||||
Scalarbase(p,r);
|
||||
Pack(sm,p);
|
||||
|
||||
for (i = 0; i < 32; i++) sm[i+32] = sk[i+32];
|
||||
crypto_hash(h,sm,n + 64);
|
||||
reduce(h);
|
||||
|
||||
for (i = 0; i < 64; i++) x[i] = 0;
|
||||
for (i = 0; i < 32; i++) x[i] = r[i]; // (U64) r[i];
|
||||
for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) x[i+j] += h[i] * d[j]; //x[i+j] += h[i] * (U64) d[j];
|
||||
modL(sm + 32,x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
I64 UnpackNeg(gf *r, U8 *p) {
|
||||
gf t, chk, num, den, den2, den4, den6;
|
||||
Set25519(r[2], gf1);
|
||||
Unpack25519(r[1], p);
|
||||
S(num, r[1]);
|
||||
M(den, num, D);
|
||||
Z(num, num, r[2]);
|
||||
A(den, r[2], den);
|
||||
|
||||
S(den2, den);
|
||||
S(den4, den2);
|
||||
M(den6, den4, den2);
|
||||
M(t, den6, num);
|
||||
M(t, t, den);
|
||||
|
||||
Pow2523(t, t);
|
||||
M(t, t, num);
|
||||
M(t, t, den);
|
||||
M(t, t, den);
|
||||
M(r[0], t, den);
|
||||
|
||||
S(chk, r[0]);
|
||||
M(chk, chk, den);
|
||||
if (Neq25519(chk, num)) M(r[0], r[0], I);
|
||||
|
||||
S(chk, r[0]);
|
||||
M(chk, chk, den);
|
||||
if (Neq25519(chk, num)) return -1;
|
||||
|
||||
if (Par25519(r[0]) == (p[31] >> 7)) Z(r[0], gf0, r[0]);
|
||||
|
||||
M(r[3], r[0], r[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 crypto_sign_open(U8 *m, U64 *mlen, U8 *sm, U64 n, U8 *pk)
|
||||
{
|
||||
I64 i;
|
||||
U8 t[32], h[64];
|
||||
gf p[4], q[4];
|
||||
|
||||
*mlen = -1;
|
||||
if (n < 64) return -1;
|
||||
|
||||
if (UnpackNeg(q, pk)) return -1;
|
||||
|
||||
for (i = 0; i < n; i++) m[i] = sm[i];
|
||||
for (i = 0; i < 32; i++) m[i+32] = pk[i];
|
||||
crypto_hash(h, m, n);
|
||||
reduce(h);
|
||||
Scalarmult(p, q, h);
|
||||
|
||||
Scalarbase(q, sm + 32);
|
||||
Add(p, q);
|
||||
Pack(t, p);
|
||||
|
||||
n -= 64;
|
||||
if (crypto_verify_32(sm, t)) {
|
||||
for (i = 0; i < n; i++) m[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) m[i] = sm[i + 64];
|
||||
*mlen = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// U8 public_key[32];
|
||||
// U8 private_key[64];
|
||||
|
||||
// crypto_box_keypair(public_key, private_key);
|
Loading…
Reference in a new issue