mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Add PFX variant
This commit is contained in:
@@ -80,6 +80,18 @@ crypto_ipcrypt_ndx_outputbytes(void)
|
||||
return crypto_ipcrypt_NDX_OUTPUTBYTES;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_ipcrypt_pfx_keybytes(void)
|
||||
{
|
||||
return crypto_ipcrypt_PFX_KEYBYTES;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_ipcrypt_pfx_bytes(void)
|
||||
{
|
||||
return crypto_ipcrypt_PFX_BYTES;
|
||||
}
|
||||
|
||||
void
|
||||
crypto_ipcrypt_keygen(unsigned char k[crypto_ipcrypt_KEYBYTES])
|
||||
{
|
||||
@@ -92,6 +104,12 @@ crypto_ipcrypt_ndx_keygen(unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
|
||||
randombytes_buf(k, crypto_ipcrypt_NDX_KEYBYTES);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_ipcrypt_pfx_keygen(unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
|
||||
{
|
||||
randombytes_buf(k, crypto_ipcrypt_PFX_KEYBYTES);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_ipcrypt_encrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
|
||||
{
|
||||
@@ -134,6 +152,18 @@ crypto_ipcrypt_ndx_decrypt(unsigned char *out, const unsigned char *in, const un
|
||||
implementation->ndx_decrypt(out, in, k);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_ipcrypt_pfx_encrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
|
||||
{
|
||||
implementation->pfx_encrypt(out, in, k);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_ipcrypt_pfx_decrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
|
||||
{
|
||||
implementation->pfx_decrypt(out, in, k);
|
||||
}
|
||||
|
||||
int
|
||||
_crypto_ipcrypt_pick_best_implementation(void)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@ typedef struct ipcrypt_implementation {
|
||||
void (*nd_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
|
||||
void (*ndx_encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k);
|
||||
void (*ndx_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
|
||||
void (*pfx_encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
|
||||
void (*pfx_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
|
||||
} ipcrypt_implementation;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -286,10 +286,204 @@ ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
|
||||
}
|
||||
|
||||
static int
|
||||
is_ipv4_mapped(const uint8_t ip16[16])
|
||||
{
|
||||
static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
|
||||
return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
|
||||
{
|
||||
return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
|
||||
{
|
||||
const size_t byte_index = 15 - bit_index / 8;
|
||||
const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
|
||||
uint8_t mask = (uint8_t) -((bit_value & 1));
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__asm__ __volatile__("" : "+r"(mask) ::);
|
||||
#endif
|
||||
ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_shift_left(uint8_t ip16[16])
|
||||
{
|
||||
BlockVec v = LOAD128(ip16);
|
||||
BlockVec shl = _mm_slli_epi64(v, 1);
|
||||
BlockVec shr = _mm_srli_epi64(v, 63);
|
||||
BlockVec car = _mm_slli_si128(shr, 8);
|
||||
v = _mm_or_si128(shl, car);
|
||||
STORE128(ip16, v);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
|
||||
{
|
||||
memset(padded_prefix, 0, 16);
|
||||
if (prefix_len_bits == 0) {
|
||||
padded_prefix[15] = 0x01;
|
||||
} else {
|
||||
padded_prefix[3] = 0x01;
|
||||
padded_prefix[14] = 0xff;
|
||||
padded_prefix[15] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t encrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
BlockVec e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(encrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
encrypted[10] = 0xff;
|
||||
encrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = XOR128(LOAD128(padded_prefix), k1keys[0]);
|
||||
e2 = XOR128(LOAD128(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS; i++) {
|
||||
e1 = AES_ENCRYPT(e1, k1keys[i]);
|
||||
e2 = AES_ENCRYPT(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_ENCRYPTLAST(e1, k1keys[ROUNDS]);
|
||||
e2 = AES_ENCRYPTLAST(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = XOR128(e1, e2);
|
||||
STORE128(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
original_bit = pfx_get_bit(in, bit_pos);
|
||||
pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, encrypted, 16);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t decrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
BlockVec e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t encrypted_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(decrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
decrypted[10] = 0xff;
|
||||
decrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = XOR128(LOAD128(padded_prefix), k1keys[0]);
|
||||
e2 = XOR128(LOAD128(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS; i++) {
|
||||
e1 = AES_ENCRYPT(e1, k1keys[i]);
|
||||
e2 = AES_ENCRYPT(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_ENCRYPTLAST(e1, k1keys[ROUNDS]);
|
||||
e2 = AES_ENCRYPTLAST(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = XOR128(e1, e2);
|
||||
STORE128(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
encrypted_bit = pfx_get_bit(in, bit_pos);
|
||||
original_bit = encrypted_bit ^ cipher_bit;
|
||||
pfx_set_bit(decrypted, bit_pos, original_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, decrypted, 16);
|
||||
}
|
||||
|
||||
struct ipcrypt_implementation ipcrypt_aesni_implementation = {
|
||||
SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
|
||||
SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
|
||||
SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
|
||||
};
|
||||
|
||||
# ifdef __clang__
|
||||
|
||||
@@ -318,10 +318,209 @@ ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
|
||||
}
|
||||
|
||||
static int
|
||||
is_ipv4_mapped(const uint8_t ip16[16])
|
||||
{
|
||||
static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
|
||||
return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
|
||||
{
|
||||
return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
|
||||
{
|
||||
const size_t byte_index = 15 - bit_index / 8;
|
||||
const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
|
||||
uint8_t mask = (uint8_t) -((bit_value & 1));
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__asm__ __volatile__("" : "+r"(mask) ::);
|
||||
#endif
|
||||
ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_shift_left(uint8_t ip16[16])
|
||||
{
|
||||
BlockVec v = LOAD128(ip16);
|
||||
const BlockVec shl = vshlq_n_u8(vreinterpretq_u8_u64(v), 1);
|
||||
const BlockVec msb = vshrq_n_u8(vreinterpretq_u8_u64(v), 7);
|
||||
const BlockVec zero = vdupq_n_u8(0);
|
||||
const BlockVec carries = vextq_u8(vreinterpretq_u8_u64(msb), zero, 1);
|
||||
v = vreinterpretq_u64_u8(vorrq_u8(shl, carries));
|
||||
STORE128(ip16, v);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
|
||||
{
|
||||
memset(padded_prefix, 0, 16);
|
||||
if (prefix_len_bits == 0) {
|
||||
padded_prefix[15] = 0x01;
|
||||
} else {
|
||||
padded_prefix[3] = 0x01;
|
||||
padded_prefix[14] = 0xff;
|
||||
padded_prefix[15] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t encrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
BlockVec e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(encrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
encrypted[10] = 0xff;
|
||||
encrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = AES_XENCRYPT(LOAD128(padded_prefix), k1keys[0]);
|
||||
e2 = AES_XENCRYPT(LOAD128(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS - 1; i++) {
|
||||
e1 = AES_XENCRYPT(e1, k1keys[i]);
|
||||
e2 = AES_XENCRYPT(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_XENCRYPTLAST(e1, k1keys[i]);
|
||||
e2 = AES_XENCRYPTLAST(e2, k2keys[i]);
|
||||
e1 = XOR128(e1, k1keys[ROUNDS]);
|
||||
e2 = XOR128(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = XOR128(e1, e2);
|
||||
STORE128(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
original_bit = pfx_get_bit(in, bit_pos);
|
||||
pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, encrypted, 16);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t decrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
BlockVec e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t encrypted_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(decrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
decrypted[10] = 0xff;
|
||||
decrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = AES_XENCRYPT(LOAD128(padded_prefix), k1keys[0]);
|
||||
e2 = AES_XENCRYPT(LOAD128(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS - 1; i++) {
|
||||
e1 = AES_XENCRYPT(e1, k1keys[i]);
|
||||
e2 = AES_XENCRYPT(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_XENCRYPTLAST(e1, k1keys[i]);
|
||||
e2 = AES_XENCRYPTLAST(e2, k2keys[i]);
|
||||
e1 = XOR128(e1, k1keys[ROUNDS]);
|
||||
e2 = XOR128(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = XOR128(e1, e2);
|
||||
STORE128(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
encrypted_bit = pfx_get_bit(in, bit_pos);
|
||||
original_bit = encrypted_bit ^ cipher_bit;
|
||||
pfx_set_bit(decrypted, bit_pos, original_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, decrypted, 16);
|
||||
}
|
||||
|
||||
struct ipcrypt_implementation ipcrypt_armcrypto_implementation = {
|
||||
SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
|
||||
SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
|
||||
SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
|
||||
};
|
||||
|
||||
# ifdef __clang__
|
||||
|
||||
@@ -260,8 +260,202 @@ ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
|
||||
}
|
||||
|
||||
static int
|
||||
is_ipv4_mapped(const uint8_t ip16[16])
|
||||
{
|
||||
static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
|
||||
return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
|
||||
{
|
||||
return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
|
||||
{
|
||||
const size_t byte_index = 15 - bit_index / 8;
|
||||
const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
|
||||
uint8_t mask = (uint8_t) -((bit_value & 1));
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__asm__ __volatile__("" : "+r"(mask) ::);
|
||||
#endif
|
||||
ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_shift_left(uint8_t ip16[16])
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 15; i++) {
|
||||
ip16[i] = (ip16[i] << 1) | (ip16[i + 1] >> 7);
|
||||
}
|
||||
ip16[15] <<= 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
|
||||
{
|
||||
memset(padded_prefix, 0, 16);
|
||||
if (prefix_len_bits == 0) {
|
||||
padded_prefix[15] = 0x01;
|
||||
} else {
|
||||
padded_prefix[3] = 0x01;
|
||||
padded_prefix[14] = 0xff;
|
||||
padded_prefix[15] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t encrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
aes_block_t e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
AES_BLOCK_STORE(diff, AES_BLOCK_XOR(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(encrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
encrypted[10] = 0xff;
|
||||
encrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k1keys[0]);
|
||||
e2 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS; i++) {
|
||||
e1 = AES_ENC(e1, k1keys[i]);
|
||||
e2 = AES_ENC(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_ENC(e1, k1keys[ROUNDS]);
|
||||
e2 = AES_ENC(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = AES_BLOCK_XOR(e1, e2);
|
||||
AES_BLOCK_STORE(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
original_bit = pfx_get_bit(in, bit_pos);
|
||||
pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, encrypted, 16);
|
||||
}
|
||||
|
||||
static void
|
||||
pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
|
||||
{
|
||||
KeySchedule k1keys;
|
||||
KeySchedule k2keys;
|
||||
uint8_t diff[16];
|
||||
uint8_t decrypted[16];
|
||||
uint8_t padded_prefix[16];
|
||||
uint8_t t[16];
|
||||
aes_block_t e1, e2, e;
|
||||
unsigned int prefix_start = 0;
|
||||
unsigned int prefix_len_bits;
|
||||
unsigned int bit_pos;
|
||||
uint8_t cipher_bit;
|
||||
uint8_t encrypted_bit;
|
||||
uint8_t original_bit;
|
||||
size_t i;
|
||||
uint8_t d;
|
||||
|
||||
expand_key(k1keys, k);
|
||||
expand_key(k2keys, k + 16);
|
||||
|
||||
AES_BLOCK_STORE(diff, AES_BLOCK_XOR(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
|
||||
d = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
d |= diff[i];
|
||||
}
|
||||
if (d == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
diff[i] = k[i] ^ 0x5a;
|
||||
}
|
||||
expand_key(k2keys, diff);
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped(in)) {
|
||||
prefix_start = 96;
|
||||
}
|
||||
|
||||
pfx_pad_prefix(padded_prefix, prefix_start);
|
||||
|
||||
memset(decrypted, 0, 16);
|
||||
if (prefix_start == 96) {
|
||||
decrypted[10] = 0xff;
|
||||
decrypted[11] = 0xff;
|
||||
}
|
||||
|
||||
for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
|
||||
e1 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k1keys[0]);
|
||||
e2 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k2keys[0]);
|
||||
for (i = 1; i < ROUNDS; i++) {
|
||||
e1 = AES_ENC(e1, k1keys[i]);
|
||||
e2 = AES_ENC(e2, k2keys[i]);
|
||||
}
|
||||
e1 = AES_ENC(e1, k1keys[ROUNDS]);
|
||||
e2 = AES_ENC(e2, k2keys[ROUNDS]);
|
||||
|
||||
e = AES_BLOCK_XOR(e1, e2);
|
||||
AES_BLOCK_STORE(t, e);
|
||||
|
||||
cipher_bit = t[15] & 1;
|
||||
bit_pos = 127 - prefix_len_bits;
|
||||
encrypted_bit = pfx_get_bit(in, bit_pos);
|
||||
original_bit = encrypted_bit ^ cipher_bit;
|
||||
pfx_set_bit(decrypted, bit_pos, original_bit);
|
||||
|
||||
pfx_shift_left(padded_prefix);
|
||||
pfx_set_bit(padded_prefix, 0, original_bit);
|
||||
}
|
||||
|
||||
memcpy(out, decrypted, 16);
|
||||
}
|
||||
|
||||
struct ipcrypt_implementation ipcrypt_soft_implementation = {
|
||||
SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
|
||||
SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt
|
||||
SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
|
||||
SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
|
||||
};
|
||||
|
||||
@@ -52,6 +52,14 @@ size_t crypto_ipcrypt_ndx_inputbytes(void);
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_ipcrypt_ndx_outputbytes(void);
|
||||
|
||||
#define crypto_ipcrypt_PFX_KEYBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_ipcrypt_pfx_keybytes(void);
|
||||
|
||||
#define crypto_ipcrypt_PFX_BYTES 16U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_ipcrypt_pfx_bytes(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_ipcrypt_keygen(unsigned char k[crypto_ipcrypt_KEYBYTES]) __attribute__((nonnull));
|
||||
|
||||
@@ -59,6 +67,10 @@ SODIUM_EXPORT
|
||||
void crypto_ipcrypt_ndx_keygen(unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_ipcrypt_pfx_keygen(unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_ipcrypt_encrypt(unsigned char out[crypto_ipcrypt_BYTES],
|
||||
const unsigned char in[crypto_ipcrypt_BYTES],
|
||||
@@ -97,6 +109,18 @@ void crypto_ipcrypt_ndx_decrypt(unsigned char out[crypto_ipcrypt_NDX_INPUT
|
||||
const unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_ipcrypt_pfx_encrypt(unsigned char out[crypto_ipcrypt_PFX_BYTES],
|
||||
const unsigned char in[crypto_ipcrypt_PFX_BYTES],
|
||||
const unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_ipcrypt_pfx_decrypt(unsigned char out[crypto_ipcrypt_PFX_BYTES],
|
||||
const unsigned char in[crypto_ipcrypt_PFX_BYTES],
|
||||
const unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
|
||||
__attribute__((nonnull));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,13 +15,17 @@ main(void)
|
||||
{
|
||||
unsigned char key[crypto_ipcrypt_KEYBYTES];
|
||||
unsigned char ndx_key[crypto_ipcrypt_NDX_KEYBYTES];
|
||||
unsigned char pfx_key[crypto_ipcrypt_PFX_KEYBYTES];
|
||||
unsigned char input[crypto_ipcrypt_BYTES];
|
||||
unsigned char output[crypto_ipcrypt_BYTES];
|
||||
unsigned char nd_output[crypto_ipcrypt_ND_OUTPUTBYTES];
|
||||
unsigned char ndx_output[crypto_ipcrypt_NDX_OUTPUTBYTES];
|
||||
unsigned char pfx_output[crypto_ipcrypt_PFX_BYTES];
|
||||
unsigned char tweak_nd[crypto_ipcrypt_ND_TWEAKBYTES];
|
||||
unsigned char tweak_ndx[crypto_ipcrypt_NDX_TWEAKBYTES];
|
||||
unsigned char decrypted[crypto_ipcrypt_BYTES];
|
||||
unsigned char encrypted1[crypto_ipcrypt_PFX_BYTES];
|
||||
unsigned char encrypted2[crypto_ipcrypt_PFX_BYTES];
|
||||
size_t i;
|
||||
|
||||
printf("crypto_ipcrypt_BYTES: %zu\n", crypto_ipcrypt_bytes());
|
||||
@@ -34,6 +38,8 @@ main(void)
|
||||
printf("crypto_ipcrypt_NDX_TWEAKBYTES: %zu\n", crypto_ipcrypt_ndx_tweakbytes());
|
||||
printf("crypto_ipcrypt_NDX_INPUTBYTES: %zu\n", crypto_ipcrypt_ndx_inputbytes());
|
||||
printf("crypto_ipcrypt_NDX_OUTPUTBYTES: %zu\n", crypto_ipcrypt_ndx_outputbytes());
|
||||
printf("crypto_ipcrypt_PFX_KEYBYTES: %zu\n", crypto_ipcrypt_pfx_keybytes());
|
||||
printf("crypto_ipcrypt_PFX_BYTES: %zu\n", crypto_ipcrypt_pfx_bytes());
|
||||
|
||||
/* Test 1: Format-preserving encryption with known key/input */
|
||||
memset(key, 0x00, sizeof key);
|
||||
@@ -197,6 +203,115 @@ main(void)
|
||||
}
|
||||
printf("OK: In-place round-trip successful\n");
|
||||
|
||||
/* Test 8: Prefix-preserving encryption (PFX mode) */
|
||||
printf("\nTest 8: Prefix-preserving encryption (PFX mode)\n");
|
||||
|
||||
/* Test vector from the specification:
|
||||
* Key: 0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301
|
||||
* Input IP: 0.0.0.0 (IPv4-mapped)
|
||||
* Expected: 151.82.155.134
|
||||
*/
|
||||
sodium_hex2bin(pfx_key, sizeof pfx_key,
|
||||
"0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301",
|
||||
64, NULL, NULL, NULL);
|
||||
|
||||
memset(input, 0, sizeof input);
|
||||
input[10] = 0xff;
|
||||
input[11] = 0xff;
|
||||
/* 0.0.0.0 */
|
||||
|
||||
printf("PFX Key: ");
|
||||
dump_hex(pfx_key, sizeof pfx_key);
|
||||
printf("Input (0.0.0.0): ");
|
||||
dump_hex(input, sizeof input);
|
||||
|
||||
crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
|
||||
printf("PFX Encrypted: ");
|
||||
dump_hex(pfx_output, sizeof pfx_output);
|
||||
|
||||
crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key);
|
||||
printf("PFX Decrypted: ");
|
||||
dump_hex(decrypted, sizeof decrypted);
|
||||
|
||||
if (memcmp(input, decrypted, sizeof input) != 0) {
|
||||
printf("FAILED: PFX decrypted does not match input\n");
|
||||
return 1;
|
||||
}
|
||||
printf("OK: PFX round-trip successful\n");
|
||||
|
||||
/* Test 9: Verify prefix preservation - IPs in same /24 should share encrypted prefix */
|
||||
printf("\nTest 9: Verify prefix preservation\n");
|
||||
|
||||
/* Use test vector key from spec */
|
||||
sodium_hex2bin(pfx_key, sizeof pfx_key,
|
||||
"2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a",
|
||||
64, NULL, NULL, NULL);
|
||||
|
||||
/* 10.0.0.47 */
|
||||
memset(input, 0, sizeof input);
|
||||
input[10] = 0xff;
|
||||
input[11] = 0xff;
|
||||
input[12] = 10;
|
||||
input[13] = 0;
|
||||
input[14] = 0;
|
||||
input[15] = 47;
|
||||
|
||||
crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
|
||||
printf("10.0.0.47 encrypted: ");
|
||||
dump_hex(encrypted1, sizeof encrypted1);
|
||||
|
||||
/* 10.0.0.129 */
|
||||
input[15] = 129;
|
||||
|
||||
crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
|
||||
printf("10.0.0.129 encrypted: ");
|
||||
dump_hex(encrypted2, sizeof encrypted2);
|
||||
|
||||
/* Check that the first 24 bits of the encrypted IPv4 addresses match (bytes 12-14) */
|
||||
if (memcmp(encrypted1 + 12, encrypted2 + 12, 3) != 0) {
|
||||
printf("FAILED: Prefix not preserved for /24 addresses\n");
|
||||
return 1;
|
||||
}
|
||||
printf("OK: /24 prefix preserved\n");
|
||||
|
||||
/* Test 10: PFX keygen */
|
||||
printf("\nTest 10: PFX key generation\n");
|
||||
crypto_ipcrypt_pfx_keygen(pfx_key);
|
||||
printf("Random PFX key generated (skipped in output)\n");
|
||||
|
||||
/* Test 11: IPv6 prefix preservation */
|
||||
printf("\nTest 11: IPv6 prefix-preserving encryption\n");
|
||||
|
||||
sodium_hex2bin(pfx_key, sizeof pfx_key,
|
||||
"2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a",
|
||||
64, NULL, NULL, NULL);
|
||||
|
||||
/* 2001:db8::1 */
|
||||
memset(input, 0, sizeof input);
|
||||
input[0] = 0x20;
|
||||
input[1] = 0x01;
|
||||
input[2] = 0x0d;
|
||||
input[3] = 0xb8;
|
||||
input[15] = 0x01;
|
||||
|
||||
crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
|
||||
printf("2001:db8::1 encrypted: ");
|
||||
dump_hex(encrypted1, sizeof encrypted1);
|
||||
|
||||
/* 2001:db8::2 */
|
||||
input[15] = 0x02;
|
||||
|
||||
crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
|
||||
printf("2001:db8::2 encrypted: ");
|
||||
dump_hex(encrypted2, sizeof encrypted2);
|
||||
|
||||
/* Check that the first 64 bits match (bytes 0-7 for /64 prefix) */
|
||||
if (memcmp(encrypted1, encrypted2, 8) != 0) {
|
||||
printf("FAILED: IPv6 /64 prefix not preserved\n");
|
||||
return 1;
|
||||
}
|
||||
printf("OK: IPv6 /64 prefix preserved\n");
|
||||
|
||||
printf("\nAll tests passed!\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -8,6 +8,8 @@ crypto_ipcrypt_NDX_KEYBYTES: 32
|
||||
crypto_ipcrypt_NDX_TWEAKBYTES: 16
|
||||
crypto_ipcrypt_NDX_INPUTBYTES: 16
|
||||
crypto_ipcrypt_NDX_OUTPUTBYTES: 32
|
||||
crypto_ipcrypt_PFX_KEYBYTES: 32
|
||||
crypto_ipcrypt_PFX_BYTES: 16
|
||||
|
||||
Test 1: Format-preserving encryption
|
||||
Key: 0102030405060708090a0b0c0d0e0f10
|
||||
@@ -49,4 +51,24 @@ OK: Deterministic encryption verified
|
||||
Test 7: In-place encryption and decryption
|
||||
OK: In-place round-trip successful
|
||||
|
||||
Test 8: Prefix-preserving encryption (PFX mode)
|
||||
PFX Key: 0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301
|
||||
Input (0.0.0.0): 00000000000000000000ffff00000000
|
||||
PFX Encrypted: 00000000000000000000ffff97529b86
|
||||
PFX Decrypted: 00000000000000000000ffff00000000
|
||||
OK: PFX round-trip successful
|
||||
|
||||
Test 9: Verify prefix preservation
|
||||
10.0.0.47 encrypted: 00000000000000000000ffff13d6d2f4
|
||||
10.0.0.129 encrypted: 00000000000000000000ffff13d6d250
|
||||
OK: /24 prefix preserved
|
||||
|
||||
Test 10: PFX key generation
|
||||
Random PFX key generated (skipped in output)
|
||||
|
||||
Test 11: IPv6 prefix-preserving encryption
|
||||
2001:db8::1 encrypted: 7cec702c12430f70d5ff5bae0021b09b
|
||||
2001:db8::2 encrypted: 7cec702c12430f70d5ff5bae0021b098
|
||||
OK: IPv6 /64 prefix preserved
|
||||
|
||||
All tests passed!
|
||||
|
||||
@@ -204,6 +204,7 @@ crypto_core_ed25519_add
|
||||
crypto_core_ed25519_bytes
|
||||
crypto_core_ed25519_from_string
|
||||
crypto_core_ed25519_from_string_ro
|
||||
crypto_core_ed25519_from_uniform
|
||||
crypto_core_ed25519_hashbytes
|
||||
crypto_core_ed25519_is_valid_point
|
||||
crypto_core_ed25519_nonreducedscalarbytes
|
||||
@@ -230,6 +231,12 @@ crypto_core_hsalsa20_constbytes
|
||||
crypto_core_hsalsa20_inputbytes
|
||||
crypto_core_hsalsa20_keybytes
|
||||
crypto_core_hsalsa20_outputbytes
|
||||
crypto_core_keccak1600_extract_bytes
|
||||
crypto_core_keccak1600_init
|
||||
crypto_core_keccak1600_permute_12
|
||||
crypto_core_keccak1600_permute_24
|
||||
crypto_core_keccak1600_statebytes
|
||||
crypto_core_keccak1600_xor_bytes
|
||||
crypto_core_ristretto255_add
|
||||
crypto_core_ristretto255_bytes
|
||||
crypto_core_ristretto255_from_hash
|
||||
@@ -310,6 +317,29 @@ crypto_hash_sha512_final
|
||||
crypto_hash_sha512_init
|
||||
crypto_hash_sha512_statebytes
|
||||
crypto_hash_sha512_update
|
||||
crypto_ipcrypt_bytes
|
||||
crypto_ipcrypt_decrypt
|
||||
crypto_ipcrypt_encrypt
|
||||
crypto_ipcrypt_keybytes
|
||||
crypto_ipcrypt_keygen
|
||||
crypto_ipcrypt_nd_decrypt
|
||||
crypto_ipcrypt_nd_encrypt
|
||||
crypto_ipcrypt_nd_inputbytes
|
||||
crypto_ipcrypt_nd_keybytes
|
||||
crypto_ipcrypt_nd_outputbytes
|
||||
crypto_ipcrypt_nd_tweakbytes
|
||||
crypto_ipcrypt_ndx_decrypt
|
||||
crypto_ipcrypt_ndx_encrypt
|
||||
crypto_ipcrypt_ndx_inputbytes
|
||||
crypto_ipcrypt_ndx_keybytes
|
||||
crypto_ipcrypt_ndx_keygen
|
||||
crypto_ipcrypt_ndx_outputbytes
|
||||
crypto_ipcrypt_ndx_tweakbytes
|
||||
crypto_ipcrypt_pfx_bytes
|
||||
crypto_ipcrypt_pfx_decrypt
|
||||
crypto_ipcrypt_pfx_encrypt
|
||||
crypto_ipcrypt_pfx_keybytes
|
||||
crypto_ipcrypt_pfx_keygen
|
||||
crypto_kdf_blake2b_bytes_max
|
||||
crypto_kdf_blake2b_bytes_min
|
||||
crypto_kdf_blake2b_contextbytes
|
||||
@@ -342,6 +372,16 @@ crypto_kdf_hkdf_sha512_statebytes
|
||||
crypto_kdf_keybytes
|
||||
crypto_kdf_keygen
|
||||
crypto_kdf_primitive
|
||||
crypto_kem_mlkem768_ciphertextbytes
|
||||
crypto_kem_mlkem768_dec
|
||||
crypto_kem_mlkem768_enc
|
||||
crypto_kem_mlkem768_enc_deterministic
|
||||
crypto_kem_mlkem768_keypair
|
||||
crypto_kem_mlkem768_publickeybytes
|
||||
crypto_kem_mlkem768_secretkeybytes
|
||||
crypto_kem_mlkem768_seed_keypair
|
||||
crypto_kem_mlkem768_seedbytes
|
||||
crypto_kem_mlkem768_sharedsecretbytes
|
||||
crypto_kx_client_session_keys
|
||||
crypto_kx_keypair
|
||||
crypto_kx_primitive
|
||||
@@ -545,6 +585,7 @@ crypto_sign_bytes
|
||||
crypto_sign_detached
|
||||
crypto_sign_ed25519
|
||||
crypto_sign_ed25519_bytes
|
||||
crypto_sign_ed25519_contextbytes_max
|
||||
crypto_sign_ed25519_detached
|
||||
crypto_sign_ed25519_keypair
|
||||
crypto_sign_ed25519_messagebytes_max
|
||||
@@ -559,6 +600,8 @@ crypto_sign_ed25519_sk_to_pk
|
||||
crypto_sign_ed25519_sk_to_seed
|
||||
crypto_sign_ed25519_verify_detached
|
||||
crypto_sign_ed25519ph_final_create
|
||||
crypto_sign_ed25519ph_final_ctx_create
|
||||
crypto_sign_ed25519ph_final_ctx_verify
|
||||
crypto_sign_ed25519ph_final_verify
|
||||
crypto_sign_ed25519ph_init
|
||||
crypto_sign_ed25519ph_statebytes
|
||||
@@ -639,6 +682,38 @@ crypto_verify_32
|
||||
crypto_verify_32_bytes
|
||||
crypto_verify_64
|
||||
crypto_verify_64_bytes
|
||||
crypto_xof_shake128
|
||||
crypto_xof_shake128_blockbytes
|
||||
crypto_xof_shake128_domain_standard
|
||||
crypto_xof_shake128_init
|
||||
crypto_xof_shake128_init_with_domain
|
||||
crypto_xof_shake128_squeeze
|
||||
crypto_xof_shake128_statebytes
|
||||
crypto_xof_shake128_update
|
||||
crypto_xof_shake256
|
||||
crypto_xof_shake256_blockbytes
|
||||
crypto_xof_shake256_domain_standard
|
||||
crypto_xof_shake256_init
|
||||
crypto_xof_shake256_init_with_domain
|
||||
crypto_xof_shake256_squeeze
|
||||
crypto_xof_shake256_statebytes
|
||||
crypto_xof_shake256_update
|
||||
crypto_xof_turboshake128
|
||||
crypto_xof_turboshake128_blockbytes
|
||||
crypto_xof_turboshake128_domain_standard
|
||||
crypto_xof_turboshake128_init
|
||||
crypto_xof_turboshake128_init_with_domain
|
||||
crypto_xof_turboshake128_squeeze
|
||||
crypto_xof_turboshake128_statebytes
|
||||
crypto_xof_turboshake128_update
|
||||
crypto_xof_turboshake256
|
||||
crypto_xof_turboshake256_blockbytes
|
||||
crypto_xof_turboshake256_domain_standard
|
||||
crypto_xof_turboshake256_init
|
||||
crypto_xof_turboshake256_init_with_domain
|
||||
crypto_xof_turboshake256_squeeze
|
||||
crypto_xof_turboshake256_statebytes
|
||||
crypto_xof_turboshake256_update
|
||||
escrypt_PBKDF2_SHA256
|
||||
escrypt_alloc_region
|
||||
escrypt_free_local
|
||||
@@ -671,6 +746,16 @@ ge25519_p3_tobytes
|
||||
ge25519_scalarmult
|
||||
ge25519_scalarmult_base
|
||||
ge25519_tobytes
|
||||
keccak1600_ref_extract_bytes
|
||||
keccak1600_ref_init
|
||||
keccak1600_ref_permute_12
|
||||
keccak1600_ref_permute_24
|
||||
keccak1600_ref_xor_bytes
|
||||
mlkem768_ref_dec
|
||||
mlkem768_ref_enc
|
||||
mlkem768_ref_enc_deterministic
|
||||
mlkem768_ref_keypair
|
||||
mlkem768_ref_seed_keypair
|
||||
randombytes
|
||||
randombytes_buf
|
||||
randombytes_buf_deterministic
|
||||
@@ -689,6 +774,16 @@ sc25519_is_canonical
|
||||
sc25519_mul
|
||||
sc25519_muladd
|
||||
sc25519_reduce
|
||||
shake128_ref
|
||||
shake128_ref_init
|
||||
shake128_ref_init_with_domain
|
||||
shake128_ref_squeeze
|
||||
shake128_ref_update
|
||||
shake256_ref
|
||||
shake256_ref_init
|
||||
shake256_ref_init_with_domain
|
||||
shake256_ref_squeeze
|
||||
shake256_ref_update
|
||||
sodium_add
|
||||
sodium_allocarray
|
||||
sodium_base642bin
|
||||
@@ -739,4 +834,20 @@ sodium_stream_salsa20_xmm6_xor_ic
|
||||
sodium_sub
|
||||
sodium_unpad
|
||||
sodium_version_string
|
||||
softaes_block_decrypt
|
||||
softaes_block_encrypt
|
||||
softaes_expand_key128
|
||||
softaes_expand_key256
|
||||
softaes_inv_mix_columns
|
||||
softaes_invert_key_schedule128
|
||||
softaes_invert_key_schedule256
|
||||
turboshake128_ref
|
||||
turboshake128_ref_init
|
||||
turboshake128_ref_init_with_domain
|
||||
turboshake128_ref_squeeze
|
||||
turboshake128_ref_update
|
||||
turboshake256_ref
|
||||
turboshake256_ref_init
|
||||
turboshake256_ref_init_with_domain
|
||||
turboshake256_ref_squeeze
|
||||
turboshake256_ref_update
|
||||
|
||||
Reference in New Issue
Block a user