From 5b1d28048601af39d4543e38231fde139d7f4010 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Sat, 23 Jan 2021 21:44:22 +0100 Subject: [PATCH] Fix 50% perf regression (2x with GCC) on binary GCD based inversion (#135) * Fix 50% perf regresion Revert part of #95, fix #134 * Deactivate inversion via addition chain for BW6-761. 2x slower than Euclid --- constantine/arithmetic/limbs.nim | 38 ++++++++++++++++++--------- constantine/curves/zoo_inversions.nim | 7 +++-- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/constantine/arithmetic/limbs.nim b/constantine/arithmetic/limbs.nim index 82cb6e3..633f2cd 100644 --- a/constantine/arithmetic/limbs.nim +++ b/constantine/arithmetic/limbs.nim @@ -246,16 +246,22 @@ func cadd*(a: var Limbs, b: Limbs, ctl: SecretBool): Carry = ## The carry is always computed whether ctl is true or false ## ## Time and memory accesses are the same whether a copy occurs or not - var t = a - result = t.add(b) - a.ccopy(t, ctl) + result = Carry(0) + var sum: SecretWord + for i in 0 ..< a.len: + addC(result, sum, a[i], b[i], result) + ctl.ccopy(a[i], sum) -func cadd*(a: var Limbs, w: SecretWord, ctl: SecretBool): Carry = +func cadd*(a: var Limbs, w: SecretWord, ctl: SecretBool): Borrow = ## Limbs conditional addition, sub a number that fits in a word ## Returns the borrow - var t = a - result = t.add(w) - a.ccopy(t, ctl) + result = Carry(0) + var diff: SecretWord + addC(result, diff, a[0], w, result) + ctl.ccopy(a[0], diff) + for i in 1 ..< a.len: + addC(result, diff, a[i], Zero, result) + ctl.ccopy(a[i], diff) func csub*(a: var Limbs, b: Limbs, ctl: SecretBool): Borrow = ## Limbs conditional substraction @@ -266,16 +272,22 @@ func csub*(a: var Limbs, b: Limbs, ctl: SecretBool): Borrow = ## The borrow is always computed whether ctl is true or false ## ## Time and memory accesses are the same whether a copy occurs or not - var t = a - result = t.sub(b) - a.ccopy(t, ctl) + result = Borrow(0) + var diff: SecretWord + for i in 0 ..< a.len: + subB(result, diff, a[i], b[i], result) + ctl.ccopy(a[i], diff) func csub*(a: var Limbs, w: SecretWord, ctl: SecretBool): Borrow = ## Limbs conditional substraction, sub a number that fits in a word ## Returns the borrow - var t = a - result = t.sub(w) - a.ccopy(t, ctl) + result = Borrow(0) + var diff: SecretWord + subB(result, diff, a[0], w, result) + ctl.ccopy(a[0], diff) + for i in 1 ..< a.len: + subB(result, diff, a[i], Zero, result) + ctl.ccopy(a[i], diff) func cneg*(a: var Limbs, ctl: CTBool) = ## Conditional negation. diff --git a/constantine/curves/zoo_inversions.nim b/constantine/curves/zoo_inversions.nim index 3619cba..8f1b07a 100644 --- a/constantine/curves/zoo_inversions.nim +++ b/constantine/curves/zoo_inversions.nim @@ -26,8 +26,11 @@ export func hasInversionAddchain*(C: static Curve): static bool = # TODO: For now we don't activate the addition chains # for Secp256k1 - # Performance is slower than GCD - when C in {BN254_Nogami, BN254_Snarks, BLS12_377, BLS12_381, BW6_761}: + # Performance is slower than GCD (to investigate) + # For BW6-761 the addition chain is over 2x slower than Euclid-based inversion + # due to multiplication being so costly with 12 limbs (grows quadratically) + # while Euclid costs grows linearly. + when C in {BN254_Nogami, BN254_Snarks, BLS12_377, BLS12_381}: true else: false