yggm/libs/f25519.cuh

141 lines
4.4 KiB
Plaintext
Raw Normal View History

2025-03-13 19:43:54 +05:00
#pragma once
2025-03-13 04:09:27 +05:00
#define F25519_SIZE 32
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_load(unsigned char* __restrict__ x, unsigned int c) {
2025-03-13 04:09:27 +05:00
#pragma unroll
for (unsigned int i = 0; i < sizeof(c); i++) {
x[i] = c & 0xFF;
c >>= 8;
}
#pragma unroll
for (unsigned int i = sizeof(c); i < F25519_SIZE; i++) {
x[i] = 0;
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_copy(unsigned char* __restrict__ x, const unsigned char* __restrict__ a) {
2025-03-13 04:09:27 +05:00
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
x[i] = a[i];
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_select(unsigned char* __restrict__ dst, const unsigned char* __restrict__ zero, const unsigned char* __restrict__ one, unsigned char cond) {
const unsigned char mask = 0 - cond;
2025-03-13 04:09:27 +05:00
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_normalize(unsigned char* __restrict__ x) {
unsigned char minusp[F25519_SIZE];
unsigned short c = (x[31] >> 7) * 19;
2025-03-13 04:09:27 +05:00
x[31] &= 127;
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
c += x[i];
2025-03-13 19:43:54 +05:00
x[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
c = 19;
#pragma unroll
for (int i = 0; i + 1 < F25519_SIZE; i++) {
c += x[i];
2025-03-13 19:43:54 +05:00
minusp[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
c += x[F25519_SIZE - 1] - 128;
2025-03-13 19:43:54 +05:00
minusp[F25519_SIZE - 1] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
f25519_select(x, minusp, x, (c >> 15) & 1);
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_add(unsigned char* __restrict__ r, const unsigned char* __restrict__ a, const unsigned char* __restrict__ b) {
unsigned short c = 0;
2025-03-13 04:09:27 +05:00
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
2025-03-13 19:43:54 +05:00
c = (c >> 8) + ((unsigned short)a[i]) + ((unsigned short)b[i]);
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
}
r[F25519_SIZE - 1] &= 127;
c = (c >> 7) * 19;
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
c += r[i];
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_sub(unsigned char* __restrict__ r, const unsigned char* __restrict__ a, const unsigned char* __restrict__ b) {
2025-03-14 19:55:09 +05:00
unsigned c = 218;
2025-03-13 04:09:27 +05:00
int i = 0;
#pragma unroll
for (i = 0; i + 1 < F25519_SIZE; i++) {
2025-03-14 19:55:09 +05:00
c += 65280 + ((unsigned)a[i]) - ((unsigned)b[i]);
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
2025-03-14 19:55:09 +05:00
c += ((unsigned)a[i]) - ((unsigned)b[i]);
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)(c & 127);
2025-03-13 04:09:27 +05:00
c = (c >> 7) * 19;
#pragma unroll
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_neg(unsigned char* __restrict__ r, const unsigned char* __restrict__ a) {
2025-03-14 19:55:09 +05:00
unsigned c = 218;
2025-03-13 04:09:27 +05:00
int i = 0;
#pragma unroll
for (i = 0; i + 1 < F25519_SIZE; i++) {
2025-03-14 19:55:09 +05:00
c += 65280 - ((unsigned)a[i]);
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
2025-03-14 19:55:09 +05:00
c -= ((unsigned)a[i]);
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)(c & 127);
2025-03-13 04:09:27 +05:00
c = (c >> 7) * 19;
#pragma unroll
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_mul__distinct(unsigned char* __restrict__ r, const unsigned char* __restrict__ a, const unsigned char* __restrict__ b) {
2025-03-14 19:55:09 +05:00
unsigned c = 0;
2025-03-13 04:09:27 +05:00
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
c >>= 8;
for (int j = 0; j <= i; j++) {
2025-03-14 19:55:09 +05:00
c += ((unsigned)a[j]) * ((unsigned)b[i - j]);
2025-03-13 04:09:27 +05:00
}
for (int j = i + 1; j < F25519_SIZE; j++) {
2025-03-14 19:55:09 +05:00
c += ((unsigned)a[j]) * ((unsigned)b[F25519_SIZE + i - j]) * 38;
2025-03-13 04:09:27 +05:00
}
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
}
r[F25519_SIZE - 1] &= 127;
c = (c >> 7) * 19;
#pragma unroll
for (int i = 0; i < F25519_SIZE; i++) {
c += r[i];
2025-03-13 19:43:54 +05:00
r[i] = (unsigned char)c;
2025-03-13 04:09:27 +05:00
c >>= 8;
}
}
2025-03-13 19:43:54 +05:00
__device__ __forceinline__ void f25519_inv__distinct(unsigned char* __restrict__ r, const unsigned char* __restrict__ x) {
unsigned char s[F25519_SIZE];
2025-03-13 04:09:27 +05:00
f25519_mul__distinct(s, x, x);
f25519_mul__distinct(r, s, x);
#pragma unroll
for (int i = 0; i < 248; i++) {
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
}
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, s);
f25519_mul__distinct(s, r, x);
f25519_mul__distinct(r, s, s);
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
2025-03-13 19:45:21 +05:00
}