Class: ECDSA::Group

Inherits:
Object
  • Object
show all
Defined in:
lib/ecdsa/group.rb,
lib/ecdsa/group/nistp192.rb,
lib/ecdsa/group/nistp224.rb,
lib/ecdsa/group/nistp256.rb,
lib/ecdsa/group/nistp384.rb,
lib/ecdsa/group/nistp521.rb,
lib/ecdsa/group/secp112r1.rb,
lib/ecdsa/group/secp112r2.rb,
lib/ecdsa/group/secp128r1.rb,
lib/ecdsa/group/secp128r2.rb,
lib/ecdsa/group/secp160k1.rb,
lib/ecdsa/group/secp160r1.rb,
lib/ecdsa/group/secp160r2.rb,
lib/ecdsa/group/secp192k1.rb,
lib/ecdsa/group/secp192r1.rb,
lib/ecdsa/group/secp224k1.rb,
lib/ecdsa/group/secp224r1.rb,
lib/ecdsa/group/secp256k1.rb,
lib/ecdsa/group/secp256r1.rb,
lib/ecdsa/group/secp384r1.rb,
lib/ecdsa/group/secp521r1.rb

Constant Summary collapse

Nistp192 =
new(
  name: 'nistp192',
  p: 62771017353866807638357894232076664160839087_00390324961279,
  a: -3,
  b: 0x64210519_e59c80e7_0fa7e9ab_72243049_feb8deec_c146b9b1,
  g: [0x188da80e_b03090f6_7cbf20eb_43a18800_f4ff0afd_82ff1012,
      0x07192b95_ffc8da78_631011ed_6b24cdd5_73f977a1_1e794811],
  n: 62771017353866807638357894231760590137671947_73182842284081,
  h: nil,  # cofactor not given in NIST document
)
Nistp224 =
new(
  name: 'nistp224',
  p: 26959946667150639794667015087019630673557916_260026308143510066298881,
  a: -3,
  b: 0xb4050a85_0c04b3ab_f5413256_5044b0b7_d7bfd8ba_270b3943_2355ffb4,
  g: [0xb70e0cbd_6bb4bf7f_321390b9_4a03c1d3_56c21122_343280d6_115c1d21,
      0xbd376388_b5f723fb_4c22dfe6_cd4375a0_5a074764_44d58199_85007e34],
  n: 26959946667150639794667015087019625940457807_714424391721682722368061,
  h: nil,  # cofactor not given in NIST document
)
Nistp256 =
new(
  name: 'nistp256',
  p: 11579208921035624876269744694940757353008614_3415290314195533631308867097853951,
  a: -3,
  b: 0x5ac635d8_aa3a93e7_b3ebbd55_769886bc_651d06b0_cc53b0f6_3bce3c3e_27d2604b,
  g: [0x6b17d1f2_e12c4247_f8bce6e5_63a440f2_77037d81_2deb33a0_f4a13945_d898c296,
      0x4fe342e2_fe1a7f9b_8ee7eb4a_7c0f9e16_2bce3357_6b315ece_cbb64068_37bf51f5],
  n: 11579208921035624876269744694940757352999695_5224135760342422259061068512044369,
  h: nil,  # cofactor not given in NIST document
)
Nistp384 =
new(
  name: 'nistp384',
  p: 39402006196394479212279040100143613805079739_27046544666794829340424572177149687032904726_6088258938001861606973112319,
  a: -3,
  b: 0xb3312fa7_e23ee7e4_988e056b_e3f82d19_181d9c6e_fe814112_0314088f_5013875a_c656398d_8a2ed19d_2a85c8ed_d3ec2aef,
  g: [0xaa87ca22_be8b0537_8eb1c71e_f320ad74_6e1d3b62_8ba79b98_59f741e0_82542a38_5502f25d_bf55296c_3a545e38_72760ab7,
      0x3617de4a_96262c6f_5d9e98bf_9292dc29_f8f41dbd_289a147c_e9da3113_b5f0b8c0_0a60b1ce_1d7e819d_7a431d7c_90ea0e5f,
     ],
  n: 39402006196394479212279040100143613805079739_27046544666794690527962765939911326356939895_6308152294913554433653942643,
  h: nil,  # cofactor not given in NIST document
)
Nistp521 =
new(
  name: 'nistp521',
  p: 68647976601306097149819007990813932172694353_00143305409394463459185543183397656052122559_64066145455497729631139148085803712198799971_6643812574028291115057151,
  a: -3,
  b: 0x051_953eb961_8e1c9a1f_929a21a0_b68540ee_a2da725b_99b315f3_b8b48991_8ef109e1_56193951_ec7e937b_1652c0bd_3bb1bf07_3573df88_3d2c34f1_ef451fd4_6b503f00,
  g: [0x00c6_858e06b7_0404e9cd_9e3ecb66_2395b442_9c648139_053fb521_f828af60_6b4d3dba_a14b5e77_efe75928_fe1dc127_a2ffa8de_3348b3c1_856a429b_f97e7e31_c2e5bd66,
      0x0118_39296a78_9a3bc004_5c8a5fb4_2c7d1bd9_98f54449_579b4468_17afbd17_273e662c_97ee7299_5ef42640_c550b901_3fad0761_353c7086_a272c240_88be9476_9fd16650],
  n: 68647976601306097149819007990813932172694353_00143305409394463459185543183397655394245057_74633321719753296399637136332111386476861244_0380340372808892707005449,
  h: nil,  # cofactor not given in NIST document
)
Secp112r1 =
new(
  name: 'secp112r1',
  p: 0xDB7C_2ABF62E3_5E668076_BEAD208B,
  a: 0xDB7C_2ABF62E3_5E668076_BEAD2088,
  b: 0x659E_F8BA0439_16EEDE89_11702B22,
  g: [0x0948_7239995A_5EE76B55_F9C2F098,
      0xA89C_E5AF8724_C0A23E0E_0FF77500],
  n: 0xDB7C_2ABF62E3_5E7628DF_AC6561C5,
  h: 1,
)
Secp112r2 =
new(
  name: 'secp112r2',
  p: 0xDB7C_2ABF62E3_5E668076_BEAD208B,
  a: 0x6127_C24C05F3_8A0AAAF6_5C0EF02C,
  b: 0x51DE_F1815DB5_ED74FCC3_4C85D709,
  g: [0x4BA3_0AB5E892_B4E1649D_D0928643,
      0xADCD_46F5882E_3747DEF3_6E956E97],
  n: 0x36DF_0AAFD8B8_D7597CA1_0520D04B,
  h: 4,
)
Secp128r1 =
new(
  name: 'secp128r1',
  p: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFF,
  a: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFC,
  b: 0xE87579C1_1079F43D_D824993C_2CEE5ED3,
  g: [0x161FF752_8B899B2D_0C28607C_A52C5B86,
      0xCF5AC839_5BAFEB13_C02DA292_DDED7A83],
  n: 0xFFFFFFFE_00000000_75A30D1B_9038A115,
  h: 1,
)
Secp128r2 =
new(
  name: 'secp128r2',
  p: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFF,
  a: 0xD6031998_D1B3BBFE_BF59CC9B_BFF9AEE1,
  b: 0x5EEEFCA3_80D02919_DC2C6558_BB6D8A5D,
  g: [0x7B6AA5D8_5E572983_E6FB32A7_CDEBC140,
      0x27B6916A_894D3AEE_7106FE80_5FC34B44],
  n: 0x3FFFFFFF_7FFFFFFF_BE002472_0613B5A3,
  h: 4,
)
Secp160k1 =
new(
  name: 'secp160k1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC73,
  a: 0,
  b: 7,
  g: [0x3B4C382C_E37AA192_A4019E76_3036F4F5_DD4D7EBB,
      0x938CF935_318FDCED_6BC28286_531733C3_F03C4FEE],
  n: 0x01_00000000_00000000_0001B8FA_16DFAB9A_CA16B6B3,
  h: 1,
)
Secp160r1 =
new(
  name: 'secp160r1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_7FFFFFFF,
  a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_7FFFFFFC,
  b: 0x1C97BEFC_54BD7A8B_65ACF89F_81D4D4AD_C565FA45,
  g: [0x4A96B568_8EF57328_46646989_68C38BB9_13CBFC82,
      0x23A62855_3168947D_59DCC912_04235137_7AC5FB32],
  n: 0x01_00000000_00000000_0001F4C8_F927AED3_CA752257,
  h: 1,
)
Secp160r2 =
new(
  name: 'secp160r2',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC73,
  a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC70,
  b: 0xB4E134D3_FB59EB8B_AB572749_04664D5A_F50388BA,
  g: [0x52DCB034_293A117E_1F4FF11B_30F7199D_3144CE6D,
      0xFEAFFEF2_E331F296_E071FA0D_F9982CFE_A7D43F2E],
  n: 0x01_00000000_00000000_0000351E_E786A818_F3A1A16B,
  h: 1,
)
Secp192k1 =
new(
  name: 'secp192k1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFEE37,
  a: 0,
  b: 3,
  g: [0xDB4FF10E_C057E9AE_26B07D02_80B7F434_1DA5D1B1_EAE06C7D,
      0x9B2F2F6D_9C5628A7_844163D0_15BE8634_4082AA88_D95E2F9D],
  n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFE_26F2FC17_0F69466A_74DEFD8D,
  h: 1,
)
Secp192r1 =
new(
  name: 'secp192r1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFF,
  a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFC,
  b: 0x64210519_E59C80E7_0FA7E9AB_72243049_FEB8DEEC_C146B9B1,
  g: [0x188DA80E_B03090F6_7CBF20EB_43A18800_F4FF0AFD_82FF1012,
      0x07192B95_FFC8DA78_631011ED_6B24CDD5_73F977A1_1E794811],
  n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_99DEF836_146BC9B1_B4D22831,
  h: 1,
)
Secp224k1 =
new(
  name: 'secp224k1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFE56D,
  a: 0,
  b: 5,
  g: [0xA1455B33_4DF099DF_30FC28A1_69A467E9_E47075A9_0F7E650E_B6B7A45C,
      0x7E089FED_7FBA3442_82CAFBD6_F7E319F7_C0B0BD59_E2CA4BDB_556D61A5],
  n: 0x01_00000000_00000000_00000000_0001DCE8_D2EC6184_CAF0A971_769FB1F7,
  h: 1,
)
Secp224r1 =
new(
  name: 'secp224r1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_00000000_00000000_00000001,
  a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFF_FFFFFFFE,
  b: 0xB4050A85_0C04B3AB_F5413256_5044B0B7_D7BFD8BA_270B3943_2355FFB4,
  g: [0xB70E0CBD_6BB4BF7F_321390B9_4A03C1D3_56C21122_343280D6_115C1D21,
      0xBD376388_B5F723FB_4C22DFE6_CD4375A0_5A074764_44D58199_85007E34],
  n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFF16A2_E0B8F03E_13DD2945_5C5C2A3D,
  h: 1,
)
Secp256k1 =
new(
  name: 'secp256k1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F,
  a: 0,
  b: 7,
  g: [0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798,
      0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8],
  n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141,
  h: 1,
)
Secp256r1 =
new(
  name: 'secp256r1',
  p: 0xFFFFFFFF_00000001_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF,
  a: 0xFFFFFFFF_00000001_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFC,
  b: 0x5AC635D8_AA3A93E7_B3EBBD55_769886BC_651D06B0_CC53B0F6_3BCE3C3E_27D2604B,
  g: [0x6B17D1F2_E12C4247_F8BCE6E5_63A440F2_77037D81_2DEB33A0_F4A13945_D898C296,
      0x4FE342E2_FE1A7F9B_8EE7EB4A_7C0F9E16_2BCE3357_6B315ECE_CBB64068_37BF51F5],
  n: 0xFFFFFFFF_00000000_FFFFFFFF_FFFFFFFF_BCE6FAAD_A7179E84_F3B9CAC2_FC632551,
  h: 1,
)
Secp384r1 =
new(
  name: 'secp384r1',
  p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_00000000_00000000_FFFFFFFF,
  a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_00000000_00000000_FFFFFFFC,
  b: 0xB3312FA7_E23EE7E4_988E056B_E3F82D19_181D9C6E_FE814112_0314088F_5013875A_C656398D_8A2ED19D_2A85C8ED_D3EC2AEF,
  g: [0xAA87CA22_BE8B0537_8EB1C71E_F320AD74_6E1D3B62_8BA79B98_59F741E0_82542A38_5502F25D_BF55296C_3A545E38_72760AB7,
      0x3617DE4A_96262C6F_5D9E98BF_9292DC29_F8F41DBD_289A147C_E9DA3113_B5F0B8C0_0A60B1CE_1D7E819D_7A431D7C_90EA0E5F],
  n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_C7634D81_F4372DDF_581A0DB2_48B0A77A_ECEC196A_CCC52973,
  h: 1,
)
Secp521r1 =
new(
  name: 'secp521r1',
  p: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF,
  a: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFC,
  b: 0x0051_953EB961_8E1C9A1F_929A21A0_B68540EE_A2DA725B_99B315F3_B8B48991_8EF109E1_56193951_EC7E937B_1652C0BD_3BB1BF07_3573DF88_3D2C34F1_EF451FD4_6B503F00,
  g: [0x00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66,
      0x011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650],
  n: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFA_51868783_BF2F966B_7FCC0148_F709A5D0_3BB5C9B8_899C47AE_BB6FB71E_91386409,
  h: 1,
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Group

These parameters are defined in www.secg.org/collateral/sec2_final.pdf

Parameters:

  • opts (Hash)

Options Hash (opts):

  • :p (Object) — default: Integer

    A prime number that defines the field used. The field will be *F<sub>p</sub>*.

  • :a (Object) — default: Integer

    The a parameter in the curve equation (*y^2 = x^3 + ax + b*).

  • :b (Object) — default: Integer

    The b parameter in the curve equation.

  • :g (Object) — default: Array(Integer)

    The coordinates of the generator point, with x first.

  • :n (Object) — default: Integer

    The order of g. This is the smallest positive integer ‘i` such that the generator point multiplied by `i` is infinity. This is also the number of different points that are on the curve.

  • :h (Object) — default: Integer

    The cofactor (optional).



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ecdsa/group.rb', line 51

def initialize(opts)
  @opts = opts

  @name = opts.fetch(:name) { '%#x' % object_id }
  @field = PrimeField.new(opts[:p])
  @param_a = opts[:a]
  @param_b = opts[:b]
  @generator = new_point(@opts[:g])
  @order = opts[:n]
  @cofactor = opts[:h]

  @param_a.is_a?(Integer) or raise ArgumentError, 'Invalid a.'
  @param_b.is_a?(Integer) or raise ArgumentError, 'Invalid b.'

  @param_a = field.mod @param_a
  @param_b = field.mod @param_b
end

Instance Attribute Details

#cofactorObject (readonly)

The cofactor of the group. This is the number of points on the curve divided by the number of points in the group generated by the generator.



26
27
28
# File 'lib/ecdsa/group.rb', line 26

def cofactor
  @cofactor
end

#fieldPrimeField (readonly)

The field that coordinates on the curve belong to.

Returns:



38
39
40
# File 'lib/ecdsa/group.rb', line 38

def field
  @field
end

#generatorPoint (readonly)

The generator point.

Returns:



15
16
17
# File 'lib/ecdsa/group.rb', line 15

def generator
  @generator
end

#nameString (readonly)

The name of the group.

Returns:

  • (String)


11
12
13
# File 'lib/ecdsa/group.rb', line 11

def name
  @name
end

#orderOrder (readonly)

The order of the group. This is the smallest positive integer ‘i` such that the generator point multiplied by `i` is infinity. This is also the number of different points that are on the curve.

Returns:

  • (Order)


21
22
23
# File 'lib/ecdsa/group.rb', line 21

def order
  @order
end

#param_aObject (readonly)

The a parameter in the curve equation (*y^2 = x^3 + ax + b*).



30
31
32
# File 'lib/ecdsa/group.rb', line 30

def param_a
  @param_a
end

#param_bInteger (readonly)

The b parameter in the curve equation.

Returns:

  • (Integer)


34
35
36
# File 'lib/ecdsa/group.rb', line 34

def param_b
  @param_b
end

Instance Method Details

#bit_lengthInteger

The number of bits that it takes to represent a member of the field. Log base 2 of the prime p, rounded up.

Returns:

  • (Integer)


97
98
99
# File 'lib/ecdsa/group.rb', line 97

def bit_length
  @bit_length ||= ECDSA.bit_length(field.prime)
end

#byte_lengthInteger

The number of bytes that it takes to represent a member of the field. Log base 256 of the prime p, rounded up.

Returns:

  • (Integer)


105
106
107
# File 'lib/ecdsa/group.rb', line 105

def byte_length
  @byte_length ||= ECDSA.byte_length(field.prime)
end

#include?(point) ⇒ Boolean

Returns true if the point is a solution to the curve’s defining equation or if it is the infinity point.

Returns:

  • (Boolean)


111
112
113
114
# File 'lib/ecdsa/group.rb', line 111

def include?(point)
  return false if point.group != self
  point.infinity? or point_satisfies_equation?(point)
end

#infinityPoint Also known as: infinity_point

Returns the infinity point.

Returns:



89
90
91
# File 'lib/ecdsa/group.rb', line 89

def infinity
  @infinity ||= Point.new(self, :infinity)
end

#inspectString

Returns:

  • (String)


143
144
145
# File 'lib/ecdsa/group.rb', line 143

def inspect
  "#<#{self.class}:#{name}>"
end

#new_point(p) ⇒ Object

Creates a new point. The argument can either be an array of integers representing the coordinates, with x first, or it can be ‘:infinity`.



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ecdsa/group.rb', line 72

def new_point(p)
  case p
  when :infinity
    infinity
  when Array
    x, y = p
    Point.new(self, x, y)
  when Integer
    generator.multiply_by_scalar(p)
  else
    raise ArgumentError, "Invalid point specifier #{p.inspect}."
  end
end

#partially_valid_public_key?(point) ⇒ Boolean

Returns true if the point is not infinity and it is a solution to the curve’s defining equation. This is defined in SEC1 2.0, Section 3.2.3.1: Elliptic Curve Public Key Partial Validation Primitive

Returns:

  • (Boolean)


129
130
131
132
133
# File 'lib/ecdsa/group.rb', line 129

def partially_valid_public_key?(point)
  return false if point.group != self
  return false if point.infinity?
  point_satisfies_equation?(point)
end

#solve_for_y(x) ⇒ Array

Given the x coordinate of a point, finds all possible corresponding y coordinates.

Returns:

  • (Array)


138
139
140
# File 'lib/ecdsa/group.rb', line 138

def solve_for_y(x)
  field.square_roots equation_right_hand_side x
end

#to_sString

Returns:

  • (String)


148
149
150
# File 'lib/ecdsa/group.rb', line 148

def to_s
  inspect
end

#valid_public_key?(point) ⇒ Boolean

Returns true if the point is not infinity, it is a solution to the curve’s defining equation, and it is a multiple of G. This process is defined in SEC1 2.0, Section 3.2.2.1: Elliptic Curve Public Key Partial Validation Primitive

Returns:

  • (Boolean)


119
120
121
122
123
124
# File 'lib/ecdsa/group.rb', line 119

def valid_public_key?(point)
  return false if point.group != self
  return false if point.infinity?
  return false if !point_satisfies_equation?(point)
  point.multiply_by_scalar(order).infinity?
end