This repo contains a simple implementation of addition, subtraction and multiplication for field elements in a finite field modulo
In particular, it uses a radix-
The goal of this code was to get familiar with Golang. It is not intended to be a reference implementation and should be used solely for educational purposes.
Make sure to have Golang installed.
The main
function of this repo contains one of the arithmetic test cases, and can be easily adjusted to try out the functions. Run it as follows:
go run .
Run all tests (in fp25519_test.go
):
go test
Notes made from slides. These are added for reference.
Represent an integer as an object with 5 limbs of 64 bits.
This is in reduced form when all
When coefficients
res[0] = a[0] + b[0]
res[1] = a[1] + b[1]
res[2] = a[2] + b[2]
res[3] = a[3] + b[3]
res[4] = a[4] + b[4]
Use signed limbs and this can work fine.
Carry for the first
carry = a[0] >> 51
a[1] += carry
carry <<== 51
a[0] -= carry
Add the carry to the next limbs and make sure the original limb is reduces to 51 bits.
Since
carry = a[4] >> 51
a[0] += 19*carry
carry <<== 51
a[4] -= carry
Because we reduced in the first few steps to 51 bits, and
r[0] = (int128) a[0]*b[0];
r[1] = (int128) a[0]*b[1] + (int128) a[1]*b[0];
r[2] = (int128) a[0]*b[2] + (int128) a[1]*b[1] + (int128) a[2]*b[0];
r[3] = (int128) a[0]*b[3] + (int128) a[1]*b[2] +
(int128) a[2]*b[1] + (int128) a[3]*a[0];
r[4] = (int128) a[0]*b[4] + (int128) a[1]*b[3] + (int128) a[2]*b[2] +
(int128) a[3]*b[1] + (int128) a[4]*a[0];
r[5] = (int128) a[1]*b[4] + (int128) a[2]*b[3] +
(int128) a[3]*b[2] + (int128) a[4]*a[1];
r[6] = (int128) a[2]*b[4] + (int128) a[3]*b[3] + (int128) a[4]*b[2];
r[7] = (int128) a[3]*b[4] + (int128) a[4]*b[3];
r[8] = (int128) a[4]*b[4];
Multiplication gives
First, reduce from 9 coefficients to 5 with:
r0=r0+19*r5
r1=r1+19*r6
r2=r2+19*r7
r3=r3+19*r8
Then carry, as before. After round 1 we have signed 64-bit integers. Therefore, we need a second round of carries to obtain reduced coefficients.