types.go raw

   1  // Package avx provides AVX2-accelerated secp256k1 operations using 128-bit limbs.
   2  //
   3  // This implementation uses 128-bit limbs stored in 256-bit AVX2 registers:
   4  //   - Scalar: 256-bit value as 2×128-bit limbs (fits in 1 YMM register)
   5  //   - FieldElement: 256-bit value as 2×128-bit limbs (fits in 1 YMM register)
   6  //   - AffinePoint: 512-bit (x,y) as 2×256-bit (fits in 2 YMM registers)
   7  //   - JacobianPoint: 768-bit (x,y,z) as 3×256-bit (fits in 3 YMM registers)
   8  package avx
   9  
  10  // Uint128 represents a 128-bit unsigned integer as two 64-bit limbs.
  11  // This is the fundamental building block for AVX2 operations.
  12  // In AVX2 assembly, two Uint128 values fit in a single YMM register.
  13  type Uint128 struct {
  14  	Lo, Hi uint64 // Lo + Hi<<64
  15  }
  16  
  17  // Scalar represents a 256-bit scalar value modulo the secp256k1 group order.
  18  // Uses 2×128-bit limbs for efficient AVX2 processing.
  19  // The entire scalar fits in a single YMM register.
  20  type Scalar struct {
  21  	D [2]Uint128 // D[0] is low 128 bits, D[1] is high 128 bits
  22  }
  23  
  24  // FieldElement represents a field element modulo the secp256k1 field prime.
  25  // Uses 2×128-bit limbs for efficient AVX2 processing.
  26  // The entire field element fits in a single YMM register.
  27  type FieldElement struct {
  28  	N [2]Uint128 // N[0] is low 128 bits, N[1] is high 128 bits
  29  }
  30  
  31  // AffinePoint represents a point on the secp256k1 curve in affine coordinates.
  32  // Uses 2 YMM registers (one for X, one for Y).
  33  type AffinePoint struct {
  34  	X, Y     FieldElement
  35  	Infinity bool
  36  }
  37  
  38  // JacobianPoint represents a point in Jacobian coordinates (X, Y, Z).
  39  // Affine coordinates are (X/Z², Y/Z³).
  40  // Uses 3 YMM registers (one each for X, Y, Z).
  41  type JacobianPoint struct {
  42  	X, Y, Z  FieldElement
  43  	Infinity bool
  44  }
  45  
  46  // Constants for secp256k1
  47  
  48  // Group order n = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
  49  var (
  50  	ScalarN = Scalar{
  51  		D: [2]Uint128{
  52  			{Lo: 0xBFD25E8CD0364141, Hi: 0xBAAEDCE6AF48A03B}, // low 128 bits
  53  			{Lo: 0xFFFFFFFFFFFFFFFE, Hi: 0xFFFFFFFFFFFFFFFF}, // high 128 bits
  54  		},
  55  	}
  56  
  57  	// 2^256 - n (used for reduction)
  58  	ScalarNC = Scalar{
  59  		D: [2]Uint128{
  60  			{Lo: 0x402DA1732FC9BEBF, Hi: 0x4551231950B75FC4}, // low 128 bits
  61  			{Lo: 0x0000000000000001, Hi: 0x0000000000000000}, // high 128 bits
  62  		},
  63  	}
  64  
  65  	// n/2 (for checking if scalar is high)
  66  	ScalarNHalf = Scalar{
  67  		D: [2]Uint128{
  68  			{Lo: 0xDFE92F46681B20A0, Hi: 0x5D576E7357A4501D}, // low 128 bits
  69  			{Lo: 0xFFFFFFFFFFFFFFFF, Hi: 0x7FFFFFFFFFFFFFFF}, // high 128 bits
  70  		},
  71  	}
  72  
  73  	ScalarZero = Scalar{}
  74  	ScalarOne  = Scalar{D: [2]Uint128{{Lo: 1, Hi: 0}, {Lo: 0, Hi: 0}}}
  75  )
  76  
  77  // Field prime p = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
  78  var (
  79  	FieldP = FieldElement{
  80  		N: [2]Uint128{
  81  			{Lo: 0xFFFFFFFEFFFFFC2F, Hi: 0xFFFFFFFFFFFFFFFF}, // low 128 bits
  82  			{Lo: 0xFFFFFFFFFFFFFFFF, Hi: 0xFFFFFFFFFFFFFFFF}, // high 128 bits
  83  		},
  84  	}
  85  
  86  	// 2^256 - p = 2^32 + 977 = 0x1000003D1
  87  	FieldPC = FieldElement{
  88  		N: [2]Uint128{
  89  			{Lo: 0x1000003D1, Hi: 0}, // low 128 bits
  90  			{Lo: 0, Hi: 0},           // high 128 bits
  91  		},
  92  	}
  93  
  94  	FieldZero = FieldElement{}
  95  	FieldOne  = FieldElement{N: [2]Uint128{{Lo: 1, Hi: 0}, {Lo: 0, Hi: 0}}}
  96  )
  97  
  98  // Generator point G for secp256k1
  99  var (
 100  	GeneratorX = FieldElement{
 101  		N: [2]Uint128{
 102  			{Lo: 0x59F2815B16F81798, Hi: 0x029BFCDB2DCE28D9},
 103  			{Lo: 0x55A06295CE870B07, Hi: 0x79BE667EF9DCBBAC},
 104  		},
 105  	}
 106  
 107  	GeneratorY = FieldElement{
 108  		N: [2]Uint128{
 109  			{Lo: 0x9C47D08FFB10D4B8, Hi: 0xFD17B448A6855419},
 110  			{Lo: 0x5DA4FBFC0E1108A8, Hi: 0x483ADA7726A3C465},
 111  		},
 112  	}
 113  
 114  	Generator = AffinePoint{
 115  		X:        GeneratorX,
 116  		Y:        GeneratorY,
 117  		Infinity: false,
 118  	}
 119  )
 120