diff --git a/constantine/arithmetic/finite_fields.nim b/constantine/arithmetic/finite_fields.nim index a396a38..d85ce4d 100644 --- a/constantine/arithmetic/finite_fields.nim +++ b/constantine/arithmetic/finite_fields.nim @@ -94,10 +94,10 @@ func cswap*(a, b: var FF, ctl: CTBool) {.meter.} = # # Note: the library currently implements generic routine for odd field modulus. # Routines for special field modulus form: -# - Mersenne Prime (2^k - 1), +# - Mersenne Prime (2ᵏ - 1), # - Generalized Mersenne Prime (NIST Prime P256: 2^256 - 2^224 + 2^192 + 2^96 - 1) # - Pseudo-Mersenne Prime (2^m - k for example Curve25519: 2^255 - 19) -# - Golden Primes (φ^2 - φ - 1 with φ = 2^k for example Ed448-Goldilocks: 2^448 - 2^224 - 1) +# - Golden Primes (φ^2 - φ - 1 with φ = 2ᵏ for example Ed448-Goldilocks: 2^448 - 2^224 - 1) # exist and can be implemented with compile-time specialization. # Note: for `+=`, double, sum diff --git a/constantine/arithmetic/limbs_montgomery.nim b/constantine/arithmetic/limbs_montgomery.nim index d88a4d5..de77075 100644 --- a/constantine/arithmetic/limbs_montgomery.nim +++ b/constantine/arithmetic/limbs_montgomery.nim @@ -471,8 +471,8 @@ func montyResidue*(r: var Limbs, a, M, r2modM: Limbs, # - Apache Milagro Crypto has an alternative implementation # that is more straightforward however: # - the exponent hamming weight is used as loop bounds -# - the base^k is stored at each index of a temp table of size k -# - the base^k to use is indexed by the hamming weight +# - the baseᵏ is stored at each index of a temp table of size k +# - the baseᵏ to use is indexed by the hamming weight # of the exponent, leaking this to cache attacks # - in contrast BearSSL touches the whole table to # hide the actual selection @@ -500,7 +500,7 @@ func montyPowPrologue( result = scratchspace.len.getWindowLen() # Precompute window content, special case for window = 1 # (i.e scratchspace has only space for 2 temporaries) - # The content scratchspace[2+k] is set at a^k + # The content scratchspace[2+k] is set at aᵏ # with scratchspace[0] untouched if result == 1: scratchspace[1] = a @@ -583,7 +583,7 @@ func montyPow*( ## - ``one`` is 1 (mod M) in montgomery representation ## - ``m0ninv`` is the montgomery magic constant "-1/M[0] mod 2^WordBitWidth" ## - ``scratchspace`` with k the window bitsize of size up to 5 - ## This is a buffer that can hold between 2^k + 1 big-ints + ## This is a buffer that can hold between 2ᵏ + 1 big-ints ## A window of of 1-bit (no window optimization) requires only 2 big-ints ## ## Note that the best window size require benchmarking and is a tradeoff between diff --git a/constantine/config/curves_parser_field.nim b/constantine/config/curves_parser_field.nim index 118aa30..70b0c5f 100644 --- a/constantine/config/curves_parser_field.nim +++ b/constantine/config/curves_parser_field.nim @@ -59,7 +59,7 @@ type ## denoted `E(𝔽p)` in Short Weierstrass form ## y² = x³ + Ax + B ## - ## If E(𝔽p^k), the elliptic curve defined over the extension field + ## If E(𝔽pᵏ), the elliptic curve defined over the extension field ## of degree k, the embedding degree, admits an isomorphism ## to a curve E'(Fp^(k/d)), we call E' a twisted curve. ## @@ -67,7 +67,7 @@ type ## y² = x³ + Ax/µ² + B/µ³ for a D-Twist (Divisor) ## or ## y² = x³ + µ²Ax + µ³B for a M-Twist (Multiplicand) - ## with the polynomial x^k - µ being irreducible. + ## with the polynomial xᵏ - µ being irreducible. ## ## i.e. if d == 2, E' is a quadratic twist and µ is a quadratic non-residue ## if d == 4, E' is a quartic twist diff --git a/constantine/config/precompute.nim b/constantine/config/precompute.nim index c77c763..d69fea5 100644 --- a/constantine/config/precompute.nim +++ b/constantine/config/precompute.nim @@ -276,7 +276,7 @@ func invModBitwidth[T: SomeUnsignedInt](a: T): T = # For a and m to be coprimes, a must be odd. # # We have the following relation - # ax ≡ 1 (mod 2^k) <=> ax(2 - ax) ≡ 1 (mod 2^(2k)) + # ax ≡ 1 (mod 2ᵏ) <=> ax(2 - ax) ≡ 1 (mod 2^(2k)) # which grows in O(log(log(a))) checkOdd(a) diff --git a/constantine/isogeny/frobenius.nim b/constantine/isogeny/frobenius.nim index e7f32a7..5b5cb7e 100644 --- a/constantine/isogeny/frobenius.nim +++ b/constantine/isogeny/frobenius.nim @@ -37,13 +37,13 @@ import # or √-2 or √-5 func frobenius_map*(r: var Fp, a: Fp, k: static int = 1) {.inline.} = - ## Computes a^(p^k) + ## Computes a^(pᵏ) ## The p-power frobenius automorphism on 𝔽p ## This is identity per Fermat's little theorem r = a func frobenius_map*(r: var Fp2, a: Fp2, k: static int = 1) {.inline.} = - ## Computes a^(p^k) + ## Computes a^(pᵏ) ## The p-power frobenius automorphism on 𝔽p2 when (k and 1) == 1: r.conj(a) @@ -54,14 +54,14 @@ func frobenius_map*(r: var Fp2, a: Fp2, k: static int = 1) {.inline.} = # ----------------------------------------------------------------- func frobenius_map*[C](r: var Fp4[C], a: Fp4[C], k: static int = 1) {.inline.} = - ## Computes a^(p^k) + ## Computes a^(pᵏ) ## The p-power frobenius automorphism on 𝔽p4 r.c0.frobenius_map(a.c0, k) r.c1.frobenius_map(a.c1, k) r.c1.mulCheckSparse frobMapConst(C, 3, k) func frobenius_map*[C](r: var Fp6[C], a: Fp6[C], k: static int = 1) {.inline.} = - ## Computes a^(p^k) + ## Computes a^(pᵏ) ## The p-power frobenius automorphism on 𝔽p6 r.c0.frobenius_map(a.c0, k) r.c1.frobenius_map(a.c1, k) @@ -77,7 +77,7 @@ func frobenius_map*[C](r: var Fp6[C], a: Fp6[C], k: static int = 1) {.inline.} = {.error: "Not Implemented".} func frobenius_map*[C](r: var Fp12[C], a: Fp12[C], k: static int = 1) {.inline.} = - ## Computes a^(p^k) + ## Computes a^(pᵏ) ## The p-power frobenius automorphism on 𝔽p12 static: doAssert r.c0 is Fp4 staticFor i, 0, r.coords.len: diff --git a/constantine/pairing/lines_common.nim b/constantine/pairing/lines_common.nim index dce8a4b..48c2722 100644 --- a/constantine/pairing/lines_common.nim +++ b/constantine/pairing/lines_common.nim @@ -19,7 +19,7 @@ import type Line*[F] = object - ## Packed line representation over a E'(Fp^k/d) + ## Packed line representation over a E'(Fpᵏ/d) ## with k the embedding degree and d the twist degree ## i.e. for a curve with embedding degree 12 and sextic twist ## F is Fp2 diff --git a/constantine/tower_field_extensions/README.md b/constantine/tower_field_extensions/README.md index 7b5927b..b480872 100644 --- a/constantine/tower_field_extensions/README.md +++ b/constantine/tower_field_extensions/README.md @@ -24,7 +24,7 @@ From Ben Edgington, https://hackmd.io/@benjaminion/bls12-381 > > Applying our rule, by substituting $x^2 = -1$, gives us the final result $(a, b) \times (c, d) =$$ac + (ad+bc)x + bdx^2 =$$(ac-bd) + (ad+bc)x =$$(ac-bd, ad+bc)$. This might look a little familiar from complex arithmetic: $(a+ib) \times (c+id) =$$(ac-bd) + (ad+bc)i$. This is not a coincidence! The complex numbers are a quadratic extension of the real numbers. > -> Complex numbers can't be extended any further because there are [no irreducible polynomials over the complex numbers](https://en.wikipedia.org/wiki/Fundamental_theorem_of_algebra). But for finite fields, if we can find an irreducible $k$-degree polynomial in our field $F_q$, and we often can, then we are able to extend the field to $F_{q^k}$, and represent the elements of the extended field as degree $k-1$ polynomials, $a_0 + a_1x +$$...$$+ a_{k-1}x^{k-1}$. We can represent this compactly as $(a_0,...,a_{k-1})$, as long as we remember that there may be some very funky arithmetic going on. +> Complex numbers can't be extended any further because there are [no irreducible polynomials over the complex numbers](https://en.wikipedia.org/wiki/Fundamental_theorem_of_algebra). But for finite fields, if we can find an irreducible $k$-degree polynomial in our field $F_q$, and we often can, then we are able to extend the field to $F_{qᵏ}$, and represent the elements of the extended field as degree $k-1$ polynomials, $a_0 + a_1x +$$...$$+ a_{k-1}x^{k-1}$. We can represent this compactly as $(a_0,...,a_{k-1})$, as long as we remember that there may be some very funky arithmetic going on. > > Also worth noting is that modular reductions like this (our reduction rule) can be chosen so that they play nicely with the twisting operation. > diff --git a/docs/optimizations.md b/docs/optimizations.md index e139436..3db6c2f 100644 --- a/docs/optimizations.md +++ b/docs/optimizations.md @@ -38,10 +38,10 @@ The optimizations can be of algebraic, algorithmic or "implementation details" n - [x] Montgomery Representation - [ ] Barret Reduction - [ ] Unsaturated Representation - - [ ] Mersenne Prime (2^k - 1), + - [ ] Mersenne Prime (2ᵏ - 1), - [ ] Generalized Mersenne Prime (NIST Prime P256: 2^256 - 2^224 + 2^192 + 2^96 - 1) - [ ] Pseudo-Mersenne Prime (2^m - k for example Curve25519: 2^255 - 19) - - [ ] Golden Primes (φ^2 - φ - 1 with φ = 2^k for example Ed448-Goldilocks: 2^448 - 2^224 - 1) + - [ ] Golden Primes (φ^2 - φ - 1 with φ = 2ᵏ for example Ed448-Goldilocks: 2^448 - 2^224 - 1) - [ ] any prime modulus (lazy carry) - Montgomery Reduction diff --git a/sage/derive_pairing.sage b/sage/derive_pairing.sage index 7df2ad1..e4ddf9b 100644 --- a/sage/derive_pairing.sage +++ b/sage/derive_pairing.sage @@ -198,7 +198,7 @@ def genFinalExp(curve_name, curve_config): scale = 3*(u^3-u^2+1) scaleDesc = ' * 3*(u^3-u^2+1)' - fexp = (p^k - 1)//r + fexp = (pᵏ - 1)//r fexp *= scale buf = f'const {curve_name}_pairing_finalexponent* = block:\n' diff --git a/tests/t_fp12_frobenius.nim b/tests/t_fp12_frobenius.nim index b0d6126..b9407e0 100644 --- a/tests/t_fp12_frobenius.nim +++ b/tests/t_fp12_frobenius.nim @@ -25,5 +25,5 @@ runFrobeniusTowerTests( Iters = 8, TestCurves = TestCurves, moduleName = "test_fp12_frobenius", - testSuiteDesc = "𝔽p12 Frobenius map: Frobenius(a, k) = a^(p^k) (mod p^12)" + testSuiteDesc = "𝔽p12 Frobenius map: Frobenius(a, k) = a^(pᵏ) (mod p^12)" ) diff --git a/tests/t_fp2_frobenius.nim b/tests/t_fp2_frobenius.nim index cc37f49..5d16237 100644 --- a/tests/t_fp2_frobenius.nim +++ b/tests/t_fp2_frobenius.nim @@ -26,5 +26,5 @@ runFrobeniusTowerTests( Iters = 8, TestCurves = TestCurves, moduleName = "test_fp2_frobenius", - testSuiteDesc = "𝔽p2 Frobenius map: Frobenius(a, k) = a^(p^k) (mod p²)" + testSuiteDesc = "𝔽p2 Frobenius map: Frobenius(a, k) = a^(pᵏ) (mod p²)" ) diff --git a/tests/t_fp4_frobenius.nim b/tests/t_fp4_frobenius.nim index fd505ab..812ce92 100644 --- a/tests/t_fp4_frobenius.nim +++ b/tests/t_fp4_frobenius.nim @@ -25,5 +25,5 @@ runFrobeniusTowerTests( Iters = 8, TestCurves = TestCurves, moduleName = "test_fp4_frobenius", - testSuiteDesc = "𝔽p4 Frobenius map: Frobenius(a, k) = a^(p^k) (mod p⁴)" + testSuiteDesc = "𝔽p4 Frobenius map: Frobenius(a, k) = a^(pᵏ) (mod p⁴)" ) diff --git a/tests/t_fp6_frobenius.nim b/tests/t_fp6_frobenius.nim index cc9701f..a7c5423 100644 --- a/tests/t_fp6_frobenius.nim +++ b/tests/t_fp6_frobenius.nim @@ -26,5 +26,5 @@ runFrobeniusTowerTests( Iters = 8, TestCurves = TestCurves, moduleName = "test_fp6_frobenius", - testSuiteDesc = "𝔽p6 Frobenius map: Frobenius(a, k) = a^(p^k) (mod p⁶)" + testSuiteDesc = "𝔽p6 Frobenius map: Frobenius(a, k) = a^(pᵏ) (mod p⁶)" )