Source code for pycoin.ecdsa.native.bignum

"""
Arrange to access a shared-object version of the bignum library using Python ctypes.
"""

import ctypes.util
import struct

from ..intstream import to_bytes


[docs]def bignum_type_for_library(library): ULONG_FACTOR = 1 << (8 * ctypes.sizeof(ctypes.c_ulong)) class BignumType(ctypes.Structure): """ The structure that's manipulated by bn, the bignum library. struct bignum_st { BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ int top; /* Index of last used d +1. */ /* The next are internal book keeping for bn_expand. */ int dmax; /* Size of the d array. */ int neg; /* one if the number is negative */ int flags; }; """ _fields_ = [ ('d', ctypes.POINTER(ctypes.c_ulong)), ('top', ctypes.c_int), ('dmax', ctypes.c_int), ('neg', ctypes.c_int), ('flags', ctypes.c_int), ] def __init__(self, n=0): "Create a BignumType from an int" negative = (n < 0) if negative: n = -n the_len = (n.bit_length() + 7)//8 sign = b'\x80' if negative else b'\0' the_bytes = struct.pack(">L", the_len+1) + sign + to_bytes(n, the_len, "big") library.BN_mpi2bn(the_bytes, the_len + 5, self) def __del__(self): "Release memory used by native library" library.BN_clear_free(self) def __int__(self): "cast to int" return self.as_int() def to_int(self): "Return this bignum's value as a Python integer." value, factor = 0, 1 for w in self.datawords(): value += w * factor factor *= ULONG_FACTOR if self.neg: value = -value return value def datawords(self): "Yield the words in the little-endian data array." return (self.d[k] for k in range(self.top)) def __repr__(self): return "BignumType(%d)" % self.to_int() return BignumType