Public-Key

從壓縮形式獲取未壓縮的公鑰

  • August 13, 2018

一個類似的問題在 Python 中有一個答案,它連結到 bitcointalk 論壇:

但我想知道如何為相同的轉換編寫 Java 程序?我注意到 Java 使用字節數據類型,我無法理解如何對值進行操作。

是的,您可以在 Java 中將 33 字節的壓縮公鑰轉換為 65 字節的未壓縮公鑰。

這是執行操作的程式碼。它是正確的、健壯的,並且只需要 Java SE 類(不需要其他庫)——但我為實現長度道歉。

import java.math.BigInteger;
import java.util.Arrays;

static final BigInteger MODULUS =
   new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
static final BigInteger CURVE_A = new BigInteger("0");
static final BigInteger CURVE_B = new BigInteger("7");


// Given a 33-byte compressed public key, this returns a 65-byte uncompressed key.
byte[] decompressPubkey(byte[] compKey) {
   // Check array length and type indicator byte
   if (compKey.length != 33 || compKey[0] != 2 && compKey[0] != 3)
       throw new IllegalArgumentException();

   final byte[] xCoordBytes = Arrays.copyOfRange(compKey, 1, compKey.length);
   final BigInteger xCoord = new BigInteger(1, xCoordBytes);  // Range [0, 2^256)

   BigInteger temp = xCoord.pow(2).add(CURVE_A);
   temp = sqrtMod(temp.add(CURVE_B));
   boolean tempIsOdd = temp.testBit(0);
   boolean yShouldBeOdd = compKey[0] == 3;
   if (tempIsOdd != yShouldBeOdd)
       temp = temp.negate().mod(MODULUS);
   final BigInteger yCoord = temp;

   // Copy the x coordinate into the new
   // uncompressed key, and change the type byte
   byte[] result = Arrays.copyOf(compKey, 65);
   result[0] = 4;

   // Carefully copy the y coordinate into uncompressed key
   final byte[] yCoordBytes = yCoord.toByteArray();
   for (int i = 0; i < 32 && i < yCoordBytes.length; i++)
       result[result.length - 1 - i] = yCoordBytes[yCoordBytes.length - 1 - i];

   return result;
}


// Given x, this returns a value y such that y^2 % MODULUS == x.
BigInteger sqrtMod(BigInteger value) {
   assert (MODULUS.intValue() & 3) == 3;
   BigInteger pow = MODULUS.add(BigInteger.ONE).shiftRight(2);
   BigInteger result = value.modPow(pow, MODULUS);
   assert result.pow(2).mod(MODULUS).equals(value);
   return result;
}

我的比特幣密碼庫確實實現了模素欄位算法,但它還應該添加解壓縮公鑰的功能……

引用自:https://bitcoin.stackexchange.com/questions/44024