github.com/cloudflare/circl@v1.5.0/dh/sidh/internal/p503/core.go (about) 1 // Code generated by go generate; DO NOT EDIT. 2 // This file was generated by robots. 3 4 package p503 5 6 import ( 7 crand "crypto/rand" 8 . "github.com/cloudflare/circl/dh/sidh/internal/common" 9 ) 10 11 // ----------------------------------------------------------------------------- 12 // Functions for traversing isogeny trees according to strategy. Key type 'A' is 13 // 14 15 // Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed 16 // for public key generation. 17 func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { 18 points := make([]ProjectivePoint, 0, 8) 19 indices := make([]int, 0, 8) 20 var i, sIdx int 21 var phi isogeny4 22 23 cparam := CalcCurveParamsEquiv4(curve) 24 strat := params.A.IsogenyStrategy 25 stratSz := len(strat) 26 27 for j := 1; j <= stratSz; j++ { 28 for i <= stratSz-j { 29 points = append(points, *xR) 30 indices = append(indices, i) 31 32 k := strat[sIdx] 33 sIdx++ 34 Pow2k(xR, &cparam, 2*k) 35 i += int(k) 36 } 37 cparam = phi.GenerateCurve(xR) 38 39 for k := 0; k < len(points); k++ { 40 phi.EvaluatePoint(&points[k]) 41 } 42 phi.EvaluatePoint(phiP) 43 phi.EvaluatePoint(phiQ) 44 phi.EvaluatePoint(phiR) 45 46 // pop xR from points 47 *xR, points = points[len(points)-1], points[:len(points)-1] 48 i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] 49 } 50 } 51 52 // Traverses isogeny tree in order to compute xR needed 53 // for public key generation. 54 func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { 55 points := make([]ProjectivePoint, 0, 8) 56 indices := make([]int, 0, 8) 57 var i, sIdx int 58 var phi isogeny4 59 60 cparam := CalcCurveParamsEquiv4(curve) 61 strat := params.A.IsogenyStrategy 62 stratSz := len(strat) 63 64 for j := 1; j <= stratSz; j++ { 65 for i <= stratSz-j { 66 points = append(points, *xR) 67 indices = append(indices, i) 68 69 k := strat[sIdx] 70 sIdx++ 71 Pow2k(xR, &cparam, 2*k) 72 i += int(k) 73 } 74 cparam = phi.GenerateCurve(xR) 75 76 for k := 0; k < len(points); k++ { 77 phi.EvaluatePoint(&points[k]) 78 } 79 80 // pop xR from points 81 *xR, points = points[len(points)-1], points[:len(points)-1] 82 i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] 83 } 84 } 85 86 // Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed 87 // for public key generation. 88 func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { 89 points := make([]ProjectivePoint, 0, 8) 90 indices := make([]int, 0, 8) 91 var i, sIdx int 92 var phi isogeny3 93 94 cparam := CalcCurveParamsEquiv3(curve) 95 strat := params.B.IsogenyStrategy 96 stratSz := len(strat) 97 98 for j := 1; j <= stratSz; j++ { 99 for i <= stratSz-j { 100 points = append(points, *xR) 101 indices = append(indices, i) 102 103 k := strat[sIdx] 104 sIdx++ 105 Pow3k(xR, &cparam, k) 106 i += int(k) 107 } 108 109 cparam = phi.GenerateCurve(xR) 110 for k := 0; k < len(points); k++ { 111 phi.EvaluatePoint(&points[k]) 112 } 113 114 phi.EvaluatePoint(phiP) 115 phi.EvaluatePoint(phiQ) 116 phi.EvaluatePoint(phiR) 117 118 // pop xR from points 119 *xR, points = points[len(points)-1], points[:len(points)-1] 120 i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] 121 } 122 } 123 124 // Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed 125 // for public key generation. 126 func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { 127 points := make([]ProjectivePoint, 0, 8) 128 indices := make([]int, 0, 8) 129 var i, sIdx int 130 var phi isogeny3 131 132 cparam := CalcCurveParamsEquiv3(curve) 133 strat := params.B.IsogenyStrategy 134 stratSz := len(strat) 135 136 for j := 1; j <= stratSz; j++ { 137 for i <= stratSz-j { 138 points = append(points, *xR) 139 indices = append(indices, i) 140 141 k := strat[sIdx] 142 sIdx++ 143 Pow3k(xR, &cparam, k) 144 i += int(k) 145 } 146 147 cparam = phi.GenerateCurve(xR) 148 for k := 0; k < len(points); k++ { 149 phi.EvaluatePoint(&points[k]) 150 } 151 152 // pop xR from points 153 *xR, points = points[len(points)-1], points[:len(points)-1] 154 i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] 155 } 156 } 157 158 // Generate a public key in the 2-torsion group. Public key is a set 159 // of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) 160 func PublicKeyGenA(pub3Pt *[3]Fp2, prvBytes []byte) { 161 var xPA, xQA, xRA ProjectivePoint 162 var xPB, xQB, xRB, xR ProjectivePoint 163 var invZP, invZQ, invZR Fp2 164 var phi isogeny4 165 166 // Load points for A 167 xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} 168 xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} 169 xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} 170 171 // Load points for B 172 xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} 173 xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} 174 xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} 175 176 // Find isogeny kernel 177 xR = ScalarMul3Pt(¶ms.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes) 178 traverseTreePublicKeyA(¶ms.InitCurve, &xR, &xPB, &xQB, &xRB) 179 180 // Secret isogeny 181 phi.GenerateCurve(&xR) 182 xPA = xPB 183 xQA = xQB 184 xRA = xRB 185 phi.EvaluatePoint(&xPA) 186 phi.EvaluatePoint(&xQA) 187 phi.EvaluatePoint(&xRA) 188 Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) 189 190 mul(&pub3Pt[0], &xPA.X, &invZP) 191 mul(&pub3Pt[1], &xQA.X, &invZQ) 192 mul(&pub3Pt[2], &xRA.X, &invZR) 193 } 194 195 // Generate a public key in the 2-torsion group. Public key is a set 196 // of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) 197 func PublicKeyGenB(pub3Pt *[3]Fp2, prvBytes []byte) { 198 var xPB, xQB, xRB, xR ProjectivePoint 199 var xPA, xQA, xRA ProjectivePoint 200 var invZP, invZQ, invZR Fp2 201 var phi isogeny3 202 203 // Load points for B 204 xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} 205 xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} 206 xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} 207 208 // Load points for A 209 xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} 210 xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} 211 xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} 212 213 // Find isogeny kernel 214 xR = ScalarMul3Pt(¶ms.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes) 215 traverseTreePublicKeyB(¶ms.InitCurve, &xR, &xPA, &xQA, &xRA) 216 217 phi.GenerateCurve(&xR) 218 xPB = xPA 219 xQB = xQA 220 xRB = xRA 221 phi.EvaluatePoint(&xPB) 222 phi.EvaluatePoint(&xQB) 223 phi.EvaluatePoint(&xRB) 224 Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) 225 226 mul(&pub3Pt[0], &xPB.X, &invZP) 227 mul(&pub3Pt[1], &xQB.X, &invZQ) 228 mul(&pub3Pt[2], &xRB.X, &invZR) 229 } 230 231 // ----------------------------------------------------------------------------- 232 // Key agreement functions 233 // 234 235 // Establishing shared keys in in 2-torsion group 236 func DeriveSecretA(ss, prv []byte, pub3Pt *[3]Fp2) { 237 var xP, xQ, xQmP ProjectivePoint 238 var xR ProjectivePoint 239 var phi isogeny4 240 var jInv Fp2 241 242 // Recover curve coefficients 243 cparam := params.InitCurve 244 RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) 245 246 // Find kernel of the morphism 247 xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} 248 xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} 249 xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} 250 xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.A.SecretBitLen, prv) 251 252 // Traverse isogeny tree 253 traverseTreeSharedKeyA(&cparam, &xR) 254 255 // Calculate j-invariant on isogenous curve 256 c := phi.GenerateCurve(&xR) 257 RecoverCurveCoefficients4(&cparam, &c) 258 Jinvariant(&cparam, &jInv) 259 FromMontgomery(&jInv, &jInv) 260 Fp2ToBytes(ss, &jInv, params.Bytelen) 261 } 262 263 // Establishing shared keys in in 3-torsion group 264 func DeriveSecretB(ss, prv []byte, pub3Pt *[3]Fp2) { 265 var xP, xQ, xQmP ProjectivePoint 266 var xR ProjectivePoint 267 var phi isogeny3 268 var jInv Fp2 269 270 // Recover curve coefficients 271 cparam := params.InitCurve 272 RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) 273 274 // Find kernel of the morphism 275 xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} 276 xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} 277 xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} 278 279 //PUBLIC KEY VALIDATION 280 if err := PublicKeyValidation(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen); err != nil { 281 _, err_read := crand.Read(ss) 282 if err_read != nil { 283 panic("core: failed to generate random ss when public key verification fails") 284 } 285 return 286 } 287 288 xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen, prv) 289 290 // Traverse isogeny tree 291 traverseTreeSharedKeyB(&cparam, &xR) 292 293 // Calculate j-invariant on isogenous curve 294 c := phi.GenerateCurve(&xR) 295 RecoverCurveCoefficients3(&cparam, &c) 296 Jinvariant(&cparam, &jInv) 297 FromMontgomery(&jInv, &jInv) 298 Fp2ToBytes(ss, &jInv, params.Bytelen) 299 300 }