* cyclotomic subgroup - 0 is not in the cyclotomic subgroup

* [doc] division is now constant-time

* Mention the newly added Pasta Curves / Halo 2 in README [skip ci]
This commit is contained in:
Mamy Ratsimbazafy 2022-04-27 14:59:14 +02:00 committed by GitHub
parent 39a8a413de
commit f678815563
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 17 additions and 24 deletions

View File

@ -10,7 +10,7 @@
> “A cryptographic system should be secure even if everything about the system, except the key, is public knowledge.”\ > “A cryptographic system should be secure even if everything about the system, except the key, is public knowledge.”\
> — Auguste Kerckhoffs > — Auguste Kerckhoffs
This library provides [constant-time](https://en.wikipedia.org/wiki/Timing_attack) implementation of cryptography protocols This library provides [constant-time](https://en.wikipedia.org/wiki/Timing_attack) implementation of cryptographic protocols
with a particular focus on pairing-based cryptography as used in blockchains and zero-knowledge protocols. with a particular focus on pairing-based cryptography as used in blockchains and zero-knowledge protocols.
The implementations are accompanied with SAGE code used as reference implementation and test vectors generators before writing highly optimized routines implemented in the [Nim language](https://nim-lang.org/) The implementations are accompanied with SAGE code used as reference implementation and test vectors generators before writing highly optimized routines implemented in the [Nim language](https://nim-lang.org/)
@ -58,7 +58,7 @@ After [installation](#installation), the available high-level protocols are:
having them be as small as possible was important. having them be as small as possible was important.
On another hand, BLS signatures were first popularized due to their succinctness. On another hand, BLS signatures were first popularized due to their succinctness.
And having signatures on G1 is useful when short signatures are desired, in embedded for example. And having signatures on G1 is useful when short signatures are desired, in embedded for example.
- [ ] SHA256 hash - [x] SHA256 hash
- ... - ...
## Curves supported in the backend ## Curves supported in the backend
@ -82,7 +82,10 @@ The following curves are configured:
- Bandersnatch, a more efficient curve embedded in BLS12-381 scalar field to be used in zk-SNARKS circuits. - Bandersnatch, a more efficient curve embedded in BLS12-381 scalar field to be used in zk-SNARKS circuits.
- Other curves - Other curves
- Edwards25519, used in ed25519 and X25519 from TLS 1.3 protocol and the Signal protocol. - Edwards25519, used in ed25519 and X25519 from TLS 1.3 protocol and the Signal protocol.
With Ristretto, it can be used in bulletproofs. With Ristretto, it can be used in bulletproofs.
- The Pasta curves (Pallas and Vesta) for the Halo 2 proof system (Zcash).
## Installation ## Installation

View File

@ -268,8 +268,7 @@ func reduce*[aLen, mLen](r: var Limbs[mLen],
) {.inline.} = ) {.inline.} =
## Reduce `a` modulo `M` and store the result in `r` ## Reduce `a` modulo `M` and store the result in `r`
## ##
## Warning ⚠: At the moment this is NOT constant-time ## This uses constant-time division
## as it relies on hardware division.
# This is implemented via type-erased indirection to avoid # This is implemented via type-erased indirection to avoid
# a significant amount of code duplication if instantiated for # a significant amount of code duplication if instantiated for
# varying bitwidth. # varying bitwidth.

View File

@ -233,8 +233,8 @@ template `-`*(x: SignedSecretWord): SignedSecretWord =
SignedSecretWord(-SecretWord(x)) SignedSecretWord(-SecretWord(x))
template `*`*(x, y: SignedSecretWord): SignedSecretWord = template `*`*(x, y: SignedSecretWord): SignedSecretWord =
# Warning ⚠️ : We assume that mul hardware multiplication is constant time # Warning ⚠️ : We assume that hardware multiplication is constant time
# but this is not always true, especially on ARMv7 and ARMv9 # but this is not always true. See https://www.bearssl.org/ctmul.html
fmap(x, `*`, y) fmap(x, `*`, y)
# shifts # shifts

View File

@ -310,14 +310,14 @@ func cyclotomic_exp*[FT](r: var FT, a: FT, exponent: BigInt, invert: bool) {.met
func isInCyclotomicSubgroup*[C](a: Fp6[C]): SecretBool = func isInCyclotomicSubgroup*[C](a: Fp6[C]): SecretBool =
## Check if a ∈ Fpⁿ: a^Φₙ(p) = 1 ## Check if a ∈ Fpⁿ: a^Φₙ(p) = 1
## Φ₆(p) = p⁴-p²+1 ## Φ₆(p) = p²-p+1
var t{.noInit.}, p{.noInit.}: Fp6[C] var t{.noInit.}, p{.noInit.}: Fp6[C]
t.frobenius_map(a, 2) # a^(p²) t.frobenius_map(a, 2) # a^(p²)
t *= a # a^(p²+1) t *= a # a^(p²+1)
p.frobenius_map(a) # a^(p) p.frobenius_map(a) # a^(p)
return t == p return t == p and not a.isZero()
func isInCyclotomicSubgroup*[C](a: Fp12[C]): SecretBool = func isInCyclotomicSubgroup*[C](a: Fp12[C]): SecretBool =
## Check if a ∈ Fpⁿ: a^Φₙ(p) = 1 ## Check if a ∈ Fpⁿ: a^Φₙ(p) = 1
@ -328,7 +328,7 @@ func isInCyclotomicSubgroup*[C](a: Fp12[C]): SecretBool =
t.frobenius_map(p2, 2) # a^(p⁴) t.frobenius_map(p2, 2) # a^(p⁴)
t *= a # a^(p⁴+1) t *= a # a^(p⁴+1)
return t == p2 return t == p2 and not a.isZero()
# ############################################################ # ############################################################
# #

View File

@ -22,15 +22,9 @@ This folder holds:
reimplement multiplication with constant-time guarantees reimplement multiplication with constant-time guarantees
(at the cost of speed and code-size) (at the cost of speed and code-size)
⚠: Currently division and modulo operations are `unsafe` Division is (naively) implemented in constant-time,
and uses hardware division. as no hardware provides constant-time division
No known CPU implements division in constant-time. While extremely slow, Constantine internals are built to avoid costly constant-time divisions.
A constant-time alternative will be provided.
While extremely slow, division and modulo are only used
on random or user inputs to constrain them to the prime field
of the elliptic curves.
Constantine internals are built to avoid costly constant-time divisions.
## Assembler ## Assembler

View File

@ -101,17 +101,14 @@ template `shl`*[T: Ct](x: T, y: SomeInteger): T = T(T.T(x) shl y)
template `*`*[T: Ct](x, y: T): T = template `*`*[T: Ct](x, y: T): T =
# Warning ⚠️ : We assume that mul hardware multiplication is constant time # Warning ⚠️ : We assume that mul hardware multiplication is constant time
# but this is not always true, especially on ARMv7 and ARMv9 # but this is not always true. See https://www.bearssl.org/ctmul.html
fmap(x, `*`, y) fmap(x, `*`, y)
template `*=`*[T: Ct](x, y: T) = template `*=`*[T: Ct](x, y: T) =
# Warning ⚠️ : We assume that mul hardware multiplication is constant time # Warning ⚠️ : We assume that mul hardware multiplication is constant time
# but this is not always true, especially on ARMv7 and ARMv9 # but this is not always true. See https://www.bearssl.org/ctmul.html
fmapAsgn(x, `*=`, y) fmapAsgn(x, `*=`, y)
# We don't implement div/mod as we can't assume the hardware implementation
# is constant-time
template `-`*[T: Ct](x: T): T = template `-`*[T: Ct](x: T): T =
## Unary minus returns the two-complement representation ## Unary minus returns the two-complement representation
## of an unsigned integer ## of an unsigned integer