use crate::base58::Pubkey;
use curve25519_dalek::edwards::CompressedEdwardsY;
use sha2::{Digest, Sha256};
const PDA_MARKER: &[u8; 21] = b"ProgramDerivedAddress";
pub fn is_on_curve(pk: &Pubkey) -> bool {
CompressedEdwardsY(*pk.as_bytes()).decompress().is_some()
}
pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8) {
let program_bytes = program_id.as_bytes();
for bump in (1u8..=255).rev() {
let mut hasher = Sha256::new();
for seed in seeds {
hasher.update(seed);
}
hasher.update([bump]);
hasher.update(program_bytes);
hasher.update(PDA_MARKER);
let hash: [u8; 32] = hasher.finalize().into();
let pda = Pubkey::from_bytes(hash);
if !is_on_curve(&pda) {
return (pda, bump);
}
}
unreachable!("no off-curve PDA found across 255 bumps (probability ~0.5^255)");
}
#[cfg(test)]
mod solana_oracle {
use super::*;
#[test]
fn matches_canonical_solana_program_derivation_two_seeds() {
let program_id = Pubkey::from_bytes([0x42u8; 32]);
let seeds: &[&[u8]] = &[b"palinurus", b"depin-attest"];
let (ref_pda, ref_bump) =
solana_program::pubkey::Pubkey::find_program_address(seeds, &solana_program::pubkey::Pubkey::new_from_array(program_id.to_bytes()));
let ref_b58 = bs58::encode(ref_pda.to_bytes()).into_string();
let (my_pda, my_bump) = find_program_address(seeds, &program_id);
eprintln!(
"[oracle] solana-program ref: {ref_b58} bump {ref_bump} | ours: {my_pda} bump {my_bump}"
);
assert_eq!(my_pda.to_bytes(), ref_pda.to_bytes(), "PDA must match canonical solana-program derivation");
assert_eq!(my_bump, ref_bump, "bump must match canonical solana-program derivation");
}
#[test]
fn matches_canonical_solana_program_derivation_single_seed() {
let program_id = Pubkey::from_bytes([0x42u8; 32]);
let seeds: &[&[u8]] = &[b"palinurus"];
let (ref_pda, ref_bump) =
solana_program::pubkey::Pubkey::find_program_address(seeds, &solana_program::pubkey::Pubkey::new_from_array(program_id.to_bytes()));
let ref_b58 = bs58::encode(ref_pda.to_bytes()).into_string();
let (my_pda, my_bump) = find_program_address(seeds, &program_id);
eprintln!(
"[oracle] solana-program ref: {ref_b58} bump {ref_bump} | ours: {my_pda} bump {my_bump}"
);
assert_eq!(my_pda.to_bytes(), ref_pda.to_bytes(), "PDA must match canonical solana-program derivation");
assert_eq!(my_bump, ref_bump, "bump must match canonical solana-program derivation");
}
}
#[cfg(test)]
mod tests {
use super::*;
fn test_program_id() -> Pubkey {
Pubkey::from_bytes([0x42; 32])
}
#[test]
fn pda_is_off_curve() {
let program_id = test_program_id();
let (pda, _bump) = find_program_address(&[b"palinurus", b"depin-attest"], &program_id);
assert!(
!is_on_curve(&pda),
"derived PDA must be off-curve (no associated private key)"
);
}
#[test]
fn pda_is_deterministic() {
let program_id = test_program_id();
let (pda1, bump1) = find_program_address(&[b"palinurus"], &program_id);
let (pda2, bump2) = find_program_address(&[b"palinurus"], &program_id);
assert_eq!(pda1, pda2, "same seeds must yield the same PDA");
assert_eq!(bump1, bump2, "same seeds must yield the same bump");
}
#[test]
fn different_seeds_yield_different_pdas() {
let program_id = test_program_id();
let (pda_a, _) = find_program_address(&[b"palinurus"], &program_id);
let (pda_b, _) = find_program_address(&[b"oracle"], &program_id);
assert_ne!(pda_a, pda_b, "different seeds must yield different PDAs");
}
#[test]
fn different_programs_yield_different_pdas() {
let seeds: &[&[u8]] = &[b"palinurus"];
let prog_a = Pubkey::from_bytes([0x42; 32]);
let prog_b = Pubkey::from_bytes([0x43; 32]);
let (pda_a, _) = find_program_address(seeds, &prog_a);
let (pda_b, _) = find_program_address(seeds, &prog_b);
assert_ne!(
pda_a, pda_b,
"same seeds under different programs must yield different PDAs"
);
}
#[test]
fn bump_is_the_highest_off_curve() {
let program_id = test_program_id();
let program_bytes = program_id.as_bytes();
let (pda, bump) = find_program_address(&[b"palinurus"], &program_id);
for higher_u16 in ((bump as u16) + 1)..=255u16 {
let higher = higher_u16 as u8;
let mut hasher = Sha256::new();
hasher.update(b"palinurus");
hasher.update([higher]);
hasher.update(program_bytes);
hasher.update(PDA_MARKER);
let h: [u8; 32] = hasher.finalize().into();
let h_pk = Pubkey::from_bytes(h);
assert!(
is_on_curve(&h_pk),
"bump {higher} is higher than returned bump {bump} but is off-curve — search order is wrong"
);
}
let mut hasher = Sha256::new();
hasher.update(b"palinurus");
hasher.update([bump]);
hasher.update(program_bytes);
hasher.update(PDA_MARKER);
let h: [u8; 32] = hasher.finalize().into();
assert_eq!(pda.to_bytes(), h, "PDA must equal sha256(seeds || bump || program || PDA_MARKER)");
}
#[test]
fn empty_seeds_still_derive_an_off_curve_pda() {
let program_id = test_program_id();
let (pda, _bump) = find_program_address(&[], &program_id);
assert!(!is_on_curve(&pda), "empty-seed PDA must still be off-curve");
}
#[test]
fn matches_solana_web3_js_reference_two_seeds() {
let expected_pda_b58: &str = "Et5CGkEYE5YqNYbReBAaBTmkZ8txz2D4kcjCVhWcvT2p";
let expected_bump: u8 = 252;
let program_id = test_program_id();
let (pda, bump) = find_program_address(&[b"palinurus", b"depin-attest"], &program_id);
assert_eq!(pda.to_string(), expected_pda_b58, "PDA base58 must match @solana/web3.js reference");
assert_eq!(bump, expected_bump, "bump must match @solana/web3.js reference");
}
#[test]
fn matches_solana_web3_js_reference_single_seed() {
let expected_pda_b58: &str = "2Jbijq1B93p6CpXv2yz4hwoz1gn3hQLFHjy7zPobWWgo";
let expected_bump: u8 = 255;
let program_id = test_program_id();
let (pda, bump) = find_program_address(&[b"palinurus"], &program_id);
assert_eq!(pda.to_string(), expected_pda_b58, "PDA base58 must match @solana/web3.js reference");
assert_eq!(bump, expected_bump, "bump must match @solana/web3.js reference");
}
}