import { describe, expect, it } from "@jest/globals"; import { decodeBase64 } from "../utils/base64.js"; import { adbGeneratePublicKey, modInverse } from "./crypto.js"; describe("modInverse", () => { it("should return correct value", () => { // https://github.com/openssl/openssl/blob/98161274636dca12e3bfafab7d2d2ac28f4d7c30/test/bntest.c#L3176 expect(modInverse(5193817943, 3259122431)).toBe(2609653924); // https://cs.android.com/android/platform/superproject/main/+/main:external/cronet/third_party/boringssl/src/crypto/fipsmodule/bn/test/mod_inv_tests.txt expect(modInverse(0, 1)).toBe(NaN); expect(modInverse(1, 1)).toBe(NaN); expect(modInverse(2, 1)).toBe(NaN); expect(modInverse(3, 1)).toBe(NaN); expect(modInverse(0x54, 0xe3)).toBe(0x64); expect(modInverse(0x2b, 0x30)).toBe(0x13); expect(modInverse(0x30, 0x37)).toBe(0x2f); expect(modInverse(0x13, 0x4b)).toBe(0x4); expect(modInverse(0xcd4, 0x6a21)).toBe(0x1c47); expect(modInverse(0x8e7, 0x49c0)).toBe(0x2b97); expect(modInverse(0xfcb, 0x3092)).toBe(0x29b9); expect(modInverse(0x14bf, 0x41ae)).toBe(0xa83); expect(modInverse(0x11b5d53e, 0x322e92a1)).toBe(0x18f15fe1); expect(modInverse(0x8af6df6, 0x33d45eb7)).toBe(0x32f9453b); expect(modInverse(0xc5f89dd5, 0xfc09c17c)).toBe(0xd696369); expect(modInverse(0x60c2526, 0x74200493)).toBe(0x622839d8); }); }); // From `adbkey` generated by Google ADB const PRIVATE_KEY = decodeBase64( `-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPlpZTBGI2GL42 XMtFF0jkgVUVQeBcLBzdvKoHhiSbXmbWsxylnWIJHNo94PxNHeic5KQTWImcZQ9L b9RWshagmqee8Ab6a/6KyP+a5voSHMWiDZmSR3AHV/PsJIUGzE+TlQgxbjq6IRHi rwGkFo2NmAmUajtI3+eSuq2AZdKj7CVe4BfrcFmMv4//92whEybk0f4Genp0N4qi EfRCkK96h3Nij3ZvqgvscCV9edFF8j7R4UMIGzNF59aGL0wWIfZiyf/W2frv2H12 lXEc3fsZq9TkU9cIwuXW/yy80XJUJVo2ZPg5z6c9SzLXSy5CCfLA9StnLjtPfuI7 CNm/jpODAgMBAAECggEACNZaU/Jt0+u9vUa6CJjzK3cuDhed246tM+tiOavGRy7/ pcg+QfavQ8AMsnGvjADn9DXvnjs4sIXE3utF2OL//5pV5HhHc8XBMltYNln672Z2 K230ybts04M1CSqM1zs/cAL6NFCDA4WA42ub4EZthEeisMTM/U865o438K1lCEFj s0+pHWYL6HSirQUYkArIGgwP+PasY8zxkGBl4D3005ZZTjVu4e/c4QCwNn2Vi40T k/7DmrXm4yQeTrctWVIMxhjWeK2EAkgc9wWRFlpOnCDulP+lnM6wshD8x18muc1j rLfRbDvDxhVv1BygqJmbj0zOxAmW8mzCsa8gVvhB4QKBgQD1ZRFVpnRnu5ixHwVx l9NI9n0G9trKQee/OpC5d1bdgYdkOXrBV85STJctvJaitpD5i4H0nLITT5fhIZLL jfcBJVkXSdwuvqaOBXWRcNmNFDqQtpazXSx1pUuCsW2l9V/gLARJe98uDRVBCVM+ 8VvC7hamUNK10GEqg76I+oGlKwKBgQDYjz7Yj5E0M9Trkps3LKLEWMENWvz40vJC 7vDIOSpOnpqtqgW+JKLC53UGgoMEnXQRnAqPbmRj8xmwf9GIAqA2vZGFf5iehCGr /RiF8RLWxFZohUDYY3B/LDm7/urax7rhiCFbmyWCAsWkllKE8uGOP9eKVOcVjXT3 iZy14FbPCQKBgBrUEuIXUbCpnNb4ekLiA3J9qEujn2XvcKPChmIQfwm2iJPXiOks bV0oDHsunBVr+kueCfYxT3K3B/bQEdl5SuDwMV5Pb+gYZeMvC5x8BvzaklCR9cXk UOEH0kqWlVNIkVPT3CAgj9TcD0/N8jD2eD7Ggulp+q9v+b+JKcKWCKiDAoGBAL0N yKKMKwo0mZOSKDixmeLpTJeZMDEVDvOJ3uAcr6d05LnpLRxCpWibYVluhGx5/IMH A10V1URATNP9sfEXwcAoHCs8KgNwfGjGCiucOoMNYhXbBrIhlWsgM8LAF00pgicz jVOIjOUEAIDfzmhMFMb3SvZzik0RceRL2WgZ0g7pAoGAauflDCIaUwJJHEz6u5/w 5XiiqZFzcgzGJAo/ZHQqPbCms/lYGvKFTurg4RSrtpqKB2kVHe1gd65EW9W/JcBQ U1Q0nKXFxhKY+bz1IqiculhINnAxyBV91s6tdhoazkdSj6XCgtSK9SP/DfiAUWm0 ytnwjm/+s2vme5fFtK9hBKo= -----END PRIVATE KEY-----` .split("\n") .slice(1, -1) .join(""), ); // From `adbkey.pub` generated by Google ADB const PUBLIC_KEY = decodeBase64( "QAAAANVsDNqDk46/2Qg74n5POy5nK/XA8glCLkvXMks9p885+GQ2WiVUctG8LP/W5cII11Pk1KsZ+90ccZV2fdjv+tnW/8li9iEWTC+G1udFMxsIQ+HRPvJF0Xl9JXDsC6pvdo9ic4d6r5BC9BGiijd0enoG/tHkJhMhbPf/j7+MWXDrF+BeJeyj0mWArbqS599IO2qUCZiNjRakAa/iESG6Om4xCJWTT8wGhSTs81cHcEeSmQ2ixRwS+uaa/8iK/mv6BvCep5qgFrJW1G9LD2WciVgTpOSc6B1N/OA92hwJYp2lHLPWZl6bJIYHqrzdHCxc4EEVVYHkSBdFy1w2vhg2YgRTlpbP00NVrZb6Car8BTqPnwTRIkHBC6nnrg6cWMQ0xusMtxChKBoYGhCLHY4iKK6ra3P1Ou1UXu0WySau3s+Av9FFXxtAuMAJUA+5GSMQGGECRhwLX910OfnHHN+VxqJkHQye4vNhIH5C1dJ39HJoxAdwH2tF7v7GF2fwsy2lUa3Vj6bBssWivCB9cKyJR0GVPZJZ1uah24ecvspwtAqbtxvj7ZD9l7AD92geEJdLrsbfhNaDyAioQ2grI32gdp80su/7BrdAsPaSomxCYBB8opmS+oJq6qTYxNZ0doT9EEyT5D9rl9UXXxq+rQbDpKV1rOQo5zJJ2GkELhUrslFm6n4+JQEAAQA=", ); describe("adbGeneratePublicKey", () => { it("should return correct value", () => { const generated = adbGeneratePublicKey(PRIVATE_KEY); expect(generated.subarray(0, 4)).toStrictEqual( PUBLIC_KEY.subarray(0, 4), ); expect(generated.subarray(4, 8)).toStrictEqual( PUBLIC_KEY.subarray(4, 8), ); expect(generated.subarray(8, 264)).toStrictEqual( PUBLIC_KEY.subarray(8, 264), ); expect(generated.subarray(265, 520)).toStrictEqual( PUBLIC_KEY.subarray(265, 520), ); expect(generated.subarray(520, 524)).toStrictEqual( PUBLIC_KEY.subarray(520, 524), ); }); it("should throw if output is too small", () => { expect(() => adbGeneratePublicKey(PRIVATE_KEY, new Uint8Array(1)), ).toThrow("output buffer is too small"); }); });