github.com/cloudflare/circl@v1.5.0/dh/sidh/internal/templates/core.gotemp (about)

     1  // Code generated by go generate; DO NOT EDIT.
     2  // This file was generated by robots.
     3  
     4  package {{.PACKAGE}}
     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(&params.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes)
   178  	traverseTreePublicKeyA(&params.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(&params.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes)
   215  	traverseTreePublicKeyB(&params.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  	
   301  }