๋น„๋ฐ€ํ‚ค, ๊ณต๊ฐœํ‚ค, ์„œ๋ช…, ๊ทธ๋ฆฌ๊ณ  ๊ฒ€์ฆ ๋ฐฉ๋ฒ•๊นŒ์ง€ ์•Œ์•„๋ณด์•˜๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ๋งŒ ํ•ด์„œ๋Š” ๊ฒฐ์ œ๋ผ๋Š” ํ–‰์œ„๊ฐ€ ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์—†๋‹ค. ์–ด๋”˜๊ฐ€๋กœ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค. ๊ทธ๋•Œ ํ•„์š”ํ•œ ๊ธฐ์ˆ ์ธ ์ง๋ ฌํ™”๋ฅผ ์•Œ์•„๋ณด์ž.

์ง๋ ฌํ™”

  • ํŠน์ • ๊ฐ์ฒด์˜ ์ •๋ณด๋ฅผ ๋น„ํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ
  • ์ด ๊ณผ์ •์—์„œ ๋ถ€ํ˜ธํ™”, ๋ณตํ˜ธํ™”๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ผ๋ จ์˜ ํ•ฉ์˜ํ•˜๋Š” ๊ทœ์น™์ด ํ•„์š”ํ•˜๋‹ค.

๋น„์••์ถ• SEC ํ˜•์‹

  • ์ผ๋‹จ S256Point๋ฅผ ์ง๋ ฌํ™”ํ•ด๋ณด์ž.
  • ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ๊ณต๊ฐœํ‚ค๋ฅผ ํ‘œํ˜„ํ•˜๊ฒŒ ๋˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
  • ๊ณต๊ฐœํ‚ค๋Š” ํƒ€์› ๊ณก์„ ์œ„์˜ ํ•œ ์ขŒํ‘œ๋ฅผ ์˜๋ฏธํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์ด๋Ÿฐ ๊ณต๊ฐœํ‚ค๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ํ˜•์‹์€ SEC(Standard for Efficient Cryptography)๋ผ ํ•œ๋‹ค.

๋ฐฉ๋ฒ•

์— ๋Œ€ํ•ด ๋น„์••์ถ• SEC ํ‘œํ˜„ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. 0x04์˜ 1๋ฐ”์ดํŠธ prefix๋กœ ์‹œ์ž‘ํ•œ๋‹ค.
  2. ๋ฅผ 32๋ฐ”์ดํŠธ Big Endian ์ •์ˆ˜๋กœ ํ‘œํ˜„ํ•œ๋‹ค. (16์ง„์ˆ˜๋กœ 64์ž)
  3. ๋ฅผ 32๋ฐ”์ดํŠธ Big Endian ์ •์ˆ˜๋กœ ํ‘œํ˜„ํ•œ๋‹ค. (16์ง„์ˆ˜๋กœ 64์ž)
  4. 1, 2, 3์„ ํ•œ๋ฐ ๋”ํ•œ๋‹ค.
047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316677

- marker: 04
- x: 7211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073
- y: dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316677
  • Big Endian, Little Endian์— ๋Œ€ํ•œ ์„ค๋ช…์€ Byte Ordering์„ ์ฐธ๊ณ ํ•˜์ž.
  • ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ๋น„ํŠธ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ์ด๋ฅผ ๋‚˜์—ดํ•˜๋Š” ์ˆœ์„œ์— ๋Œ€ํ•œ ๊ฒƒ์ด๋‹ค.
  • Big Endian์˜ ๊ฒฝ์šฐ ์šฐ๋ฆฌ๊ฐ€ ์ผ๋ฐ˜ ์ˆซ์ž๋ฅผ ์“ฐ๋“ฏ, ์•ž์— ํฐ ๋‹จ์œ„๋ฅผ ์˜๋ฏธํ•˜๋Š” ์ˆซ์ž๊ฐ€ ์˜ค๊ณ ,
    • 0x182 = 2561 + 168 + 1*2 =
  • Little Endian์˜ ๊ฒฝ์šฐ ๊ทธ ์—ญ์ˆœ์œผ๋กœ ๋œ๋‹ค.
    • 0x182 = 11 + 168 + 2*256 =
  • ๋น„ํŠธ๋ฅผ ์–ด๋–ค ์ˆœ์„œ๋กœ ๋‚˜์—ดํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ์ด๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ๋‚˜์˜ค๋Š” ๊ฒฐ๊ณผ๊ฐ’์ด ์ƒ์ดํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์–ด๋– ํ•œ ๊ทœ์น™์œผ๋กœ ์ €์žฅํ•˜๋Š”์ง€๋Š” ์ค‘์š”ํ•œ ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค.

๊ตฌํ˜„

class S256Point(Point):
...
    def sec(self):
        return b'\x04' + self.x.num.to_bytes(32, 'big') + self.y.num.to_bytes(32, 'big')
  • b'\x04'๋Š” python์—์„œ bytes ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
  • ์ž์„ธํ•œ ๊ฒƒ์€ 47.3 bytes, bytearray ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.
  • to_bytes()ํ•จ์ˆ˜๋Š” ์ •์ˆ˜ํ˜•์„ bytes ํ˜•์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
    • 32: ๊ธธ์ด
    • โ€˜bigโ€™: ๋ฐฉ์‹

์••์ถ• SEC ํ˜•์‹

  • ๊ณต๊ฐœํ‚ค๋Š” ๊ฒฐ๊ตญ ํƒ€์› ๊ณก์„  ์œ„์˜ ํ•œ ์ ์ด๋‹ค.
  • ์ด ํŠน์„ฑ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๊ตณ์ด ๊ณต๊ฐœํ‚ค๋ฅผ ์••์ถ•ํ•  ๋•Œ, ๋‘๊ฐœ์˜ ๊ฐ’์„ ๋‹ด์•„์„œ ๋ณด๋‚ผ ํ•„์š”๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋Œ€์‹  ๊ฐ’ ํ•˜๋‚˜๋งŒ ๋ณด๋‚ด๊ณ , ๋ฐ›๋Š”์ชฝ์—์„œ ์ด๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๊ฐ’์„ ์–ป์œผ๋ฉด ๋œ๋‹ค.
    • ๋‹ค๋งŒ ์—ฐ์‚ฐ๋ ฅ์ด ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ ์ €์žฅ ๋น„์šฉ์ด ์ค‘์š”ํ•œ์ง€ ๊ณ„์‚ฐ ๋น„์šฉ์ด ์ค‘์š”ํ•œ์ง€ ํŒ๋‹จํ•  ํ•„์š”๋Š” ์žˆ๋‹ค.

  • ์••์ถ• SEC ํ˜•์‹์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด๋Š”, x๋งŒ ์ œ๊ณตํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ y๊ฐ’์€ ๊ณ„์‚ฐํ•˜์ž.
  • ๊ทธ๋ฆฌ๊ณ  ๊ทธ y๊ฐ’์˜ ๊ฒฐ์ •์€ ํƒ€์› ๊ณก์„  ์œ„์—์„œ ๋™์ผ x์— ๋Œ€ํ•œ ํ•ด๋“ค์˜ ๋Œ€์นญ์  ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์†Œํ•œ์˜ ์ •๋ณด๋งŒ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒฐ์ •์ง“์ž๋Š” ๊ฒƒ์ด๋‹ค.
  • ์‰ฝ๊ฒŒ ์ƒ๊ฐํ•ด๋ณด์ž.
  • x๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ ํƒ€์› ๊ณก์„ ์—์„œ ํ•ด๋Š” ๋‘๊ฐœ์ด๋ฉฐ ๋Œ€์นญ์ด๋‹ค.
  • ์œ ํ•œ์ฒด์—์„œ p์˜ ๊ฐ’์€ 2๋ณด๋‹ค ํฐ ์†Œ์ˆ˜์ด๋‹ค. ์ฆ‰ โ€œํ™€์ˆ˜โ€์ด๋‹ค.
  • ์œ„์ชฝ์˜ ํ•ด์˜ y๊ฐ’์ด ํ™€์ˆ˜์ธ ๊ฒฝ์šฐ
    • ์•„๋ž˜์ชฝ p-y = ํ™€์ˆ˜-ํ™€์ˆ˜ = ์ง์ˆ˜
  • ์œ„์ชฝ์˜ ํ•ด์˜ y๊ฐ’์ด ์ง์ˆ˜์ธ ๊ฒฝ์šฐ
    • ์•„๋ž˜์ชฝ p-y = ํ™€์ˆ˜-์ง์ˆ˜ = ํ™€์ˆ˜
  • ์ฆ‰, x๊ฐ’๊ณผ, ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ์€ y๊ฐ’์˜ ํ™€์ˆ˜/์ง์ˆ˜ ์—ฌ๋ถ€๋งŒ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํƒ€์› ๊ณก์„  ์œ„์˜ ํŠน์ • ์ขŒํ‘œ๋ฅผ ํŠน์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋™์ž‘ ๋ฐฉ์‹ ์ •๋ฆฌ

ํƒ€์› ๊ณก์„  ์œ„์˜ ์ (๊ณต๊ฐœํ‚ค)๋ฅผ ๋ณด๋‚ด๊ณ  ์‹ถ์€์ชฝ์„ A, ๋ฐ›๋Š”์ชฝ์„ B๋ผ ํ•˜๊ฒ ๋‹ค.

  1. A๋Š” ๋ณด๋‚ด๊ณ  ์‹ถ์€ ์ ์„ ๊ตฌํ•œ๋‹ค.
  2. y๊ฐ’์˜ ํ™€์ˆ˜/์ง์ˆ˜ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค.
  3. x์™€ y์˜ ํ™€์ˆ˜/์ง์ˆ˜์—ฌ๋ถ€๋ฅผ ์ง๋ ฌํ™”ํ•˜์—ฌ ๋ณด๋‚ธ๋‹ค.
  4. B๋Š” x์™€ y์˜ ํ™€์ˆ˜/์ง์ˆ˜์—ฌ๋ถ€๋ฅผ ํŒŒ์‹ฑํ•œ๋‹ค.
  5. ์ด๋ฏธ ์„œ๋กœ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ํƒ€์›๊ณก์„ ์— x๋ฅผ ์ ์šฉํ•œ๋‹ค.
  6. ๊ฒฐ๊ณผ๋กœ ๋‚˜์˜จ ๋‘๊ฐœ์˜ y์— ๋Œ€ํ•ด ํ™€์ˆ˜/์ง์ˆ˜์— ๋”ฐ๋ผ ๊ฐ’์„ ๊ฒฐ์ •ํ•œ๋‹ค.

ํ‘œํ˜„ ๋ฐฉ์‹

0349c4e631e3624a545de3f89f5d8684c7b81386d94bdd531d2e213bf016b278a

- y marker - 03
  - even: 02
  - odd: 03
- ร— - 49c4e631e3624a545de3f89f5d8684c7b81386d94bdd531d2e213bf016b278a(32 bytes)

๊ตฌํ˜„

class S256Point(Point):
...
    def sec(self, compressed=True):
        '''returns the binary version of the SEC format'''
        if compressed:
            if self.y.num % 2 == 0:
                return b'\x02' + self.x.num.to_bytes(32, 'big')
            else:
                return b'\x03' + self.x.num.to_bytes(32, 'big')
        else:
            return b'\x04' + self.x.num.to_bytes(32, 'big') + \
                self.y.num.to_bytes(32, 'big')
...

๊ฒฐ๊ณผ

  • 65byte์—์„œ 33byte๋กœ ์ค„์–ด๋“ค์—ˆ๋‹ค.
  • ์—ฐ์‚ฐ๋Ÿ‰ ์ ˆ์•ฝ๊ณผ ๊ณต๊ฐ„ ์ ˆ์•ฝ ๋‘๊ฐœ์˜ ์ธก๋ฉด์„ ๋น„๊ตํ–ˆ์„ ๋–„ ๋น„ํŠธ์ฝ”์ธ์˜ ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜์„ ๋ชจ์œผ๊ณ , ์ด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—
  • ๊ณต๊ฐ„ ์ ˆ์•ฝ ์ธก๋ฉด์ด ๋” ์˜ํ–ฅ๋ ฅ์ด ํฌ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์••์ถ• ๋ฐฉ์‹์„ ์“ฐ๋Š” ๊ฒƒ์ด ๋” ์ข‹๋‹ค.

ํŒŒ์‹ฑ ๋ฐฉ๋ฒ•

  • ๋ณด๋‚ผ ๋•Œ๋Š” ์ €๋ ‡๊ฒŒ ๋ณด๋‚ด๋”๋ผ๋„, ๋ฐ›๋Š”์ชฝ์—์„œ๋Š” ๊ฒฐ๊ตญ ๊ณ„์‚ฐ์„ ํ•ด์•ผ ํ•œ๋‹ค.
  • ๋™์ผ ์— ๋Œ€ํ•ด ๋Œ€์นญ์ ์ธ ๋‘๊ฐœ์˜ ๊ฐ€ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜ํ•™ ๋ฌธ์ œ๋ฅผ ํ’€์–ด์•ผ ํ•œ๋‹ค.

ํ’€์ด ๋ฐฉ๋ฒ•

  • ํŽ˜๋ฅด๋งˆ์˜ ์†Œ์ •๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์€ ์œ„์™€ ๊ฐ™์ด ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์—ฌ๊ธฐ์„œ ๊ฐ’์€ ๋ฌด์Šจ ๊ฐ’์ผ๊นŒ?
  • ์œ ํ•œ์ฒด์—์„œ ์ •์˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์šฉ๋˜๋Š” ์ˆ˜ ์—ญ์‹œ ์œ ํ•œ์ฒด์˜ ํŠน์„ฑ์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค.
  • ์ฆ‰, ์œ„์ˆ˜๋ณด๋‹ค ์ž‘์€ ์ˆ˜์—ฌ์•ผ ํ•˜๋ฉฐ, ์ •์ˆ˜์—ฌ์•ผ ํ•œ๋‹ค.
  • secp256k1์—์„œ ์‚ฌ์šฉํ•˜๋Š” p๋Š” ์„ ๋งŒ์กฑํ•œ๋‹ค.
  • ์ฆ‰, ์ด๋˜์–ด ์ •์ˆ˜๊ฐ€ ๋œ๋‹ค.

ํŒŒ์‹ฑ ๋ฐฉ๋ฒ•

  • ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ ์•Œ์•˜์œผ๋‹ˆ, ์ด์ œ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.
  • ์œ„์—์„œ ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•์„ ์•Œ์•˜์œผ๋‹ˆ ์ฝ”๋“œ๋กœ ์ ์šฉํ•ด๋ณด์ž.
class S256Field(FieldElement):
...
    def sqrt(self):
        return self**((P + 1) // 4)
 
class S256Point(Point):
...
    @classmethod
    def parse(self, sec_bin): # SEC ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Œ
        '''returns a Point object from a SEC binary (not hex)'''
        if sec_bin[0] == 4:  # ์ฒซ ๊ฐ’์ด 4๋ผ๋ฉด, ๋น„์••์ถ•์ž„
            x = int.from_bytes(sec_bin[1:33], 'big')
            y = int.from_bytes(sec_bin[33:65], 'big')
            return S256Point(x=x, y=y)
        is_even = sec_bin[0] == 2  # 2๋‚˜, 3์ด๋ผ๋ฉด ์••์ถ•๋ฐฉ์‹์ž„
        x = S256Field(int.from_bytes(sec_bin[1:], 'big'))
        # right side of the equation y^2 = x^3 + 7
        alpha = x**3 + S256Field(B) # B = 7
        # solve for left side
        beta = alpha.sqrt()  # y๊ฐ’์„ ๊ตฌํ•จ
        if beta.num % 2 == 0:  #  ์ง์ˆ˜๋ผ๋ฉด ํ™€์ˆ˜๊ฐ’๋„ ๊ตฌํ•ด์ค˜์•ผ ํ•จ
            even_beta = beta
            odd_beta = S256Field(P - beta.num)
        else: # ํ™€์ˆ˜๋ผ๋ฉด ์ง์ˆ˜๊ฐ’๋„ ๊ตฌํ•ด์ค˜์•ผ ํ•จ
            even_beta = S256Field(P - beta.num)
            odd_beta = beta
        if is_even: # ์ตœ์ข…์ ์œผ๋กœ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ ํ™€/์ง ์š”์ฒญ์— ๋”ฐ๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ
            return S256Point(x, even_beta)
        else:
            return S256Point(x, odd_beta)

Reference