Skip to content

Commit

Permalink
rearranges the crypto package into separate nips and reduces the amou…
Browse files Browse the repository at this point in the history
…nt of circular dependencies.
  • Loading branch information
vitorpamplona committed Jun 25, 2024
1 parent 79ace7f commit a8a2bda
Show file tree
Hide file tree
Showing 34 changed files with 460 additions and 453 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import com.vitorpamplona.ammolite.relays.Client
import com.vitorpamplona.ammolite.service.HttpClientManager
import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.crypto.nip06.Nip06
import com.vitorpamplona.quartz.encoders.Hex
import com.vitorpamplona.quartz.encoders.Nip19Bech32
import com.vitorpamplona.quartz.encoders.bechToBytes
Expand Down Expand Up @@ -129,8 +128,8 @@ class AccountStateViewModel : ViewModel() {
proxyPort = proxyPort,
signer = NostrSignerInternal(keyPair),
)
} else if (key.contains(" ") && Nip06().isValidMnemonic(key)) {
val keyPair = KeyPair(privKey = Nip06().privateKeyFromMnemonic(key))
} else if (key.contains(" ") && CryptoUtils.isValidMnemonic(key)) {
val keyPair = KeyPair(privKey = CryptoUtils.privateKeyFromMnemonic(key))
Account(
keyPair,
proxy = proxy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CryptoBenchmark {
val keyPair2 = KeyPair()

benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.getSharedSecretNIP44v1(keyPair1.privKey!!, keyPair2.pubKey))
assertNotNull(CryptoUtils.nip44.v1.getSharedSecret(keyPair1.privKey!!, keyPair2.pubKey))
}
}

Expand All @@ -70,7 +70,7 @@ class CryptoBenchmark {
val keyPair2 = KeyPair()

benchmarkRule.measureRepeated {
assertNotNull(CryptoUtils.computeSharedSecretNIP44v1(keyPair1.privKey!!, keyPair2.pubKey))
assertNotNull(CryptoUtils.nip44.v1.computeSharedSecret(keyPair1.privKey!!, keyPair2.pubKey))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class GiftWrapReceivingBenchmark {

benchmarkRule.measureRepeated {
assertNotNull(
CryptoUtils.decryptNIP44v2(
CryptoUtils.decryptNIP44(
wrap.content,
receiver.keyPair.privKey!!,
wrap.pubKey.hexToByteArray(),
Expand All @@ -182,7 +182,7 @@ class GiftWrapReceivingBenchmark {
val wrap = createWrap(sender, receiver)

val innerJson =
CryptoUtils.decryptNIP44v2(
CryptoUtils.decryptNIP44(
wrap.content,
receiver.keyPair.privKey!!,
wrap.pubKey.hexToByteArray(),
Expand All @@ -200,7 +200,7 @@ class GiftWrapReceivingBenchmark {

benchmarkRule.measureRepeated {
assertNotNull(
CryptoUtils.decryptNIP44v2(
CryptoUtils.decryptNIP44(
seal.content,
receiver.keyPair.privKey!!,
seal.pubKey.hexToByteArray(),
Expand All @@ -217,7 +217,7 @@ class GiftWrapReceivingBenchmark {
val seal = createSeal(sender, receiver)

val innerJson =
CryptoUtils.decryptNIP44v2(
CryptoUtils.decryptNIP44(
seal.content,
receiver.keyPair.privKey!!,
seal.pubKey.hexToByteArray(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CryptoUtilsTest {
val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f"

val key =
CryptoUtils.getSharedSecretNIP44v1(
CryptoUtils.nip44.v1.getSharedSecret(
privateKey = privateKey.hexToByteArray(),
pubKey = publicKey.hexToByteArray(),
)
Expand All @@ -56,8 +56,8 @@ class CryptoUtilsTest {
val sender = KeyPair()
val receiver = KeyPair()

val sharedSecret1 = CryptoUtils.getSharedSecretNIP44v1(sender.privKey!!, receiver.pubKey)
val sharedSecret2 = CryptoUtils.getSharedSecretNIP44v1(receiver.privKey!!, sender.pubKey)
val sharedSecret1 = CryptoUtils.nip44.v1.getSharedSecret(sender.privKey!!, receiver.pubKey)
val sharedSecret2 = CryptoUtils.nip44.v1.getSharedSecret(receiver.privKey!!, sender.pubKey)

assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey())

Expand Down Expand Up @@ -88,8 +88,8 @@ class CryptoUtilsTest {
val privateKey = CryptoUtils.privkeyCreate()
val publicKey = CryptoUtils.pubkeyCreate(privateKey)

val encrypted = CryptoUtils.encryptNIP44v1(msg, privateKey, publicKey)
val decrypted = CryptoUtils.decryptNIP44v1(encrypted, privateKey, publicKey)
val encrypted = CryptoUtils.nip44.v1.encrypt(msg, privateKey, publicKey)
val decrypted = CryptoUtils.nip44.v1.decrypt(encrypted, privateKey, publicKey)

assertEquals(msg, decrypted)
}
Expand All @@ -113,10 +113,10 @@ class CryptoUtilsTest {

val privateKey = CryptoUtils.privkeyCreate()
val publicKey = CryptoUtils.pubkeyCreate(privateKey)
val sharedSecret = CryptoUtils.getSharedSecretNIP44v1(privateKey, publicKey)
val sharedSecret = CryptoUtils.nip44.v1.getSharedSecret(privateKey, publicKey)

val encrypted = CryptoUtils.encryptNIP44v1(msg, sharedSecret)
val decrypted = CryptoUtils.decryptNIP44v1(encrypted, sharedSecret)
val encrypted = CryptoUtils.nip44.v1.encrypt(msg, sharedSecret)
val decrypted = CryptoUtils.nip44.v1.decrypt(encrypted, sharedSecret)

assertEquals(msg, decrypted)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,45 @@ package com.vitorpamplona.quartz.crypto.nip06

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.encoders.toHexKey
import fr.acinq.secp256k1.Secp256k1
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class Bip32SeedDerivationTest {
val seedDerivation = Bip32SeedDerivation(Secp256k1.get())

val masterBitcoin =
Bip32SeedDerivation.generate(
seedDerivation.generate(
Bip39Mnemonics.toSeed("gun please vital unable phone catalog explain raise erosion zoo truly exist", ""),
)

val nostrMnemonic0 =
Bip32SeedDerivation.generate(
seedDerivation.generate(
Bip39Mnemonics.toSeed("leader monkey parrot ring guide accident before fence cannon height naive bean", ""),
)

val nostrMnemonic1 =
Bip32SeedDerivation.generate(
seedDerivation.generate(
Bip39Mnemonics.toSeed("what bleak badge arrange retreat wolf trade produce cricket blur garlic valid proud rude strong choose busy staff weather area salt hollow arm fade", ""),
)

@Test
fun restoreBIP44Wallet() {
val privateKey = Bip32SeedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/44'/1'/0'"))
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/44'/1'/0'"))
assertEquals("50b3e7905c642309c8a8b73df5a49757a10f2bebb5804571b9db9004cce8a190", privateKey.toHexKey())
}

@Test
fun restoreBIP49Wallet() {
val privateKey = Bip32SeedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/49'/1'/0'"))
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/49'/1'/0'"))
assertEquals("154c02c0b66899291a19012207642ba096a2d3ebf51baf153c9495976feb1b30", privateKey.toHexKey())
}

@Test
fun restoreBIP84Wallet() {
val privateKey = Bip32SeedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/84'/1'/0'"))
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/84'/1'/0'"))
assertEquals("53e8c09a0e3ddcd8d68821c1e99e823966e99df91fb253e1f453a443ba543cb2", privateKey.toHexKey())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ package com.vitorpamplona.quartz.crypto.nip06

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.encoders.toHexKey
import fr.acinq.secp256k1.Secp256k1
import junit.framework.TestCase.assertEquals
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class Nip06Test {
val nip06 = Nip06(Secp256k1.get())

// private key (hex): 7f7ff03d123792d6ac594bfa67bf6d0c0ab55b6b1fdb6249303fe861f1ccba9a
// nsec: nsec10allq0gjx7fddtzef0ax00mdps9t2kmtrldkyjfs8l5xruwvh2dq0lhhkp
private val menemonic0 = "leader monkey parrot ring guide accident before fence cannon height naive bean"
Expand All @@ -43,26 +46,26 @@ class Nip06Test {

@Test
fun fromSeedNip06TestVector0() {
val privateKeyHex = Nip06().privateKeyFromMnemonic(menemonic0).toHexKey()
val privateKeyHex = nip06.privateKeyFromMnemonic(menemonic0).toHexKey()
assertEquals("7f7ff03d123792d6ac594bfa67bf6d0c0ab55b6b1fdb6249303fe861f1ccba9a", privateKeyHex)

val privateKeyHex21 = Nip06().privateKeyFromMnemonic(menemonic0, 21).toHexKey()
val privateKeyHex21 = nip06.privateKeyFromMnemonic(menemonic0, 21).toHexKey()
assertEquals("576390ec69951fcfbf159f2aac0965bb2e6d7a07da2334992af3225c57eaefca", privateKeyHex21)
}

@Test
fun fromSeedNip06TestVector1() {
val privateKeyHex = Nip06().privateKeyFromMnemonic(menemonic1).toHexKey()
val privateKeyHex = nip06.privateKeyFromMnemonic(menemonic1).toHexKey()
assertEquals("c15d739894c81a2fcfd3a2df85a0d2c0dbc47a280d092799f144d73d7ae78add", privateKeyHex)

val privateKeyHex21 = Nip06().privateKeyFromMnemonic(menemonic1, 42).toHexKey()
val privateKeyHex21 = nip06.privateKeyFromMnemonic(menemonic1, 42).toHexKey()
assertEquals("ad993054383da74e955f8b86346365b5ffd6575992e1de3738dda9f94407052b", privateKeyHex21)
}

@Test
@Ignore("Snort is not correctly implemented")
fun fromSeedNip06FromSnort() {
val privateKeyNsec = Nip06().privateKeyFromMnemonic(snortTest).toHexKey()
val privateKeyNsec = nip06.privateKeyFromMnemonic(snortTest).toHexKey()
assertEquals("nsec1ppw9ltr2x9qwg9a2qnmgv98tfruy2ejnja7me76mwmsreu3s8u2sscj5nt", privateKeyNsec)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.crypto
package com.vitorpamplona.quartz.crypto.nip44

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.encoders.hexToByteArray
import com.vitorpamplona.quartz.encoders.toHexKey
import fr.acinq.secp256k1.Secp256k1
Expand Down Expand Up @@ -79,8 +80,7 @@ class NIP44v2Test {
v.plaintext!!,
conversationKey1,
v.nonce!!.hexToByteArray(),
)
.encodePayload()
).encodePayload()

assertEquals(v.payload, ciphertext)

Expand All @@ -107,8 +107,7 @@ class NIP44v2Test {
plaintext,
conversationKey,
v.nonce!!.hexToByteArray(),
)
.encodePayload()
).encodePayload()

assertEquals(v.payloadSha256, sha256Hex(ciphertext.toByteArray(Charsets.UTF_8)))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.crypto
package com.vitorpamplona.quartz.crypto.nip49

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.encoders.toHexKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.encoders

import com.vitorpamplona.quartz.crypto.CryptoUtils
import org.junit.Assert.assertEquals
Expand All @@ -31,8 +31,8 @@ class HexEncodingTest {
fun testHexEncodeDecodeOurs() {
assertEquals(
testHex,
com.vitorpamplona.quartz.encoders.Hex.encode(
com.vitorpamplona.quartz.encoders.Hex.decode(testHex),
Hex.encode(
Hex.decode(testHex),
),
)
}
Expand All @@ -42,7 +42,8 @@ class HexEncodingTest {
assertEquals(
testHex,
fr.acinq.secp256k1.Hex.encode(
fr.acinq.secp256k1.Hex.decode(testHex),
fr.acinq.secp256k1.Hex
.decode(testHex),
),
)
}
Expand All @@ -51,14 +52,17 @@ class HexEncodingTest {
fun testRandoms() {
for (i in 0..1000) {
val bytes = CryptoUtils.privkeyCreate()
val hex = fr.acinq.secp256k1.Hex.encode(bytes)
val hex =
fr.acinq.secp256k1.Hex
.encode(bytes)
assertEquals(
fr.acinq.secp256k1.Hex.encode(bytes),
com.vitorpamplona.quartz.encoders.Hex.encode(bytes),
fr.acinq.secp256k1.Hex
.encode(bytes),
Hex.encode(bytes),
)
assertEquals(
bytes.toList(),
com.vitorpamplona.quartz.encoders.Hex.decode(hex).toList(),
Hex.decode(hex).toList(),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.encoders

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.encoders.LnInvoiceUtil
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,10 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.encoders

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.encoders.Hex
import com.vitorpamplona.quartz.encoders.Nip19Bech32
import com.vitorpamplona.quartz.encoders.decodePrivateKeyAsHexOrNull
import com.vitorpamplona.quartz.encoders.hexToByteArray
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.FhirResourceEvent
import com.vitorpamplona.quartz.events.TextNoteEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.events

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.events.ChatroomKey
import kotlinx.collections.immutable.persistentSetOf
import org.junit.Assert.assertEquals
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.events

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.TextNoteEvent
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz
package com.vitorpamplona.quartz.events

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.events.Event
import org.junit.Test
import org.junit.runner.RunWith

Expand Down
Loading

1 comment on commit a8a2bda

@vitorpamplona
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greenart7c3 FYI, I just moved some stuff around on the quartz lib. It might need some updates on Amber's side.

Please sign in to comment.